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)