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)