如何手动中断ajax,如何中断Promise?

本文探讨了如何在Promise链中实现中断操作,通过创建新Promise并返回其pending状态来提前结束后续then/catch/finally的执行。重点讲解了超时网络请求的中断处理、中断函数的设计和应用场景,以及如何根据用户交互手动终止Promise。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Promise 有个缺点就是一旦创建就无法取消,所以本质上 Promise 是无法被终止的,但我们在开发过程中可能会遇到下面两个需求:

中断调用链

就是在某个 then/catch 执行之后,不想让后续的链式调用继续执行了,即:

somePromise

.then(() => {})

.then(() => {

// 终止 Promise 链,让下面的 then、catch 和 finally 都不执行

})

.then(() => console.log('then'))

.catch(() => console.log('catch'))

.finally(() => console.log('finally'))

复制代码

答案就是在 then/catch 的最后一行返回一个永远 pending 的 promise 即可:

return new Promise((resolve, reject) => {})

复制代码

这样的话后面所有的 then、catch 和 finally 都不会执行了。

中断Promise

注意这里是中断而不是终止,因为 Promise 无法终止,这个中断的意思是:在合适的时候,把 pending 状态的 promise 给 reject 掉。例如一个常见的应用场景就是希望给网络请求设置超时时间,一旦超时就就中断,我们这里用定时器模拟一个网络请求,随机 3 秒之内返回:

const request = new Promise((resolve, reject) => {

setTimeout(() => {

resolve('收到服务端数据')

}, Math.random() * 3000)

})

复制代码

如果认为超过 2 秒就是网络超时,可以对该 promise 写一个包装函数 timeoutWrapper:

function timeoutWrapper(p, timeout = 2000){

const wait = new Promise((resolve, reject) => {

setTimeout(() => {

reject('请求超时')

}, timeout)

})

return Promise.race([p, wait])

}

复制代码

于是就可以像下面这样用了:

const req = timeoutWrapper(request)

req.then(res => console.log(res)).catch(e => console.log(e))

复制代码

不过这种方式并不灵活,因为终止 promise 的原因可能有很多,例如当用户点击某个按钮或者出现其他事件时手动终止。所以应该写一个包装函数,提供 abort 方法,让使用者自己决定何时终止:

function abortWrapper(p1){

let abort

let p2 = new Promise((resolve, reject) => (abort = reject))

let p = Promise.race([p1, p2])

p.abort = abort

return p

}

复制代码

使用方法如下:

const req = abortWrapper(request)

req.then(res => console.log(res)).catch(e => console.log(e))

setTimeout(() => req.abort('用户手动终止请求'), 2000) // 这里可以是用户主动点击

复制代码

最后,再次强调一下,虽然 promise 被中断了,但是 promise 并没有终止,网络请求依然可能返回,只不过那时我们已经不关心请求结果了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值