promise常见问题总结
promise如何中断
promise的缺点之一就是无法让promise中断
Promise.resolve().then(() => {
console.log('then 1')
}).then(() => {
console.log('then 2')
}).then(() => {
console.log('then 3')
}).catch((err) => {
console.log(err)
})
如上代码如何让promise的链式调用中断?
- 一种方法是在then 1中直接抛错, 这样就不会执行then 2, then 3, 直接跳到catch方法打印err(但此方法并没有实际中断)
Promise.resolve().then(() => {
console.log('then 1')
throw new Error('xxx')
}).then(() => {
console.log('then 2')
}).then(() => {
console.log('then 3')
}).catch((err) => {
console.log(err)
})
- 另一种方法就是在then 1中return 一个新的Promise,但不改变其状态,这样该Promise就一直处于pedding状态,即不会执行后面任何方法
Promise.resolve().then(() => {
console.log('then 1')
return new Promise(() => {})
}).then(() => {
console.log('then 2')
}).then(() => {
console.log('then 3')
}).catch((err) => {
console.log(err)
})
- 中断有啥用? ———- 可以让我想到超时中断问题
假设我们要用promsie自己封装一个ajax, 设置超时中断时间,如果没返回就不用返回了, 返回也不做处理了,不重要(虽然和上面的原理没关系,但不重要,上面是一个promsie的链式调用中断,此例是实际应用中的问题,你管我用几个promsie呢, 想到了记录一下)
function wrap(p1) {
let abort
let p2 = new Promise((resolve, reject) => {
abort = reject
})
let p = Promise.race([p1, p2])
// 将延时promise的reject方法挂在到p1与p2的race后的promise上, 可以在方法外通过调用p的cancel方法,来触发p2的reject
p.cancel = abort
return p
}
let fn = wrap(new Promise((resolve, reject) => {
// 假设1秒后ajax返回, 调用resolve
setTimeout(() => {
resolve()
}, 1000)
}))
fn.then(() => {
console.log('ok')
}).catch(() => {
console.log('err')
})
// 设置延时时间500ms, 如果500ms数据买回来,就中断
setTimeout(() => {
fn.cancel()
}, 500)
发表回复