乐趣区

关于javascript:promisethen里有个promise

new Promise((res) => {console.log('p1');
    res()}).then(() => {console.log('p1-t1');
    new Promise((res) => {console.log('p2');
        res();}).then(() => {console.log('p2-t1');
    }).then(() => {console.log('p2-t2');
    });
}).then(() => {console.log('p1-t2')
});

// p1 -> p1-t1 -> p2 -> p2-t1 -> p1-t2 -> p2-t2
  • p1 和 p1-t1 不难理解,整体代码块是一个 macro-task,promise 实例化过程中传入的函数会立马执行,故先输入 p1,而后记录 then 里的回调,期待 res 被执行,排入 micro-task 队列里,故第二个输入的是 p1-t1
  • 同理外部的 promise 立马执行,注册回调,调用 res,先后输入 p2 和 p2-t1
  • 但这里咱们可能会有纳闷为什么 p1-t2 是在 p2-t1 之后触发的,最开始内部 promise 注册回调的时候不应该先把 p1-t2 记录下来,而后才轮到 p2-t1?注册时的先后顺序是对的,但调用机会不同,因为 promise then 会返回一个 promise,所以第二个 then 中执行回调的机会取决于第一个 then 返回的 promise 什么时候调用 res
  • 而第一个 promise then 返回的 promise,就是 then 外面的函数,相当于,then 会将传入的函数用 new promise 包装一层,而后依据他的返回决定什么时候执行 res,如果函数返回是一个 promise 的话,then 包装的 promise 会将其 res 办法交给返回的 promise 的 then 解决,而如果返回的是非 promise(没有写 return,等同于返回 undefined),则会在执行完回调的时候主动执行 then 包装的 promise 的 res
  • 所以 p2 输入之后,执行了外部 promise 的 res,p2-t1 被推入 micro-task 队列,而后内部 promise 的第一个 then 执行结束,没有返回,调用暗藏的 res,执行第二个 then 回调,p1-t2 推入 micro-task 队列
  • 所以先 p2-t1,再 p1-t2
  • 最初同理,外部 promise 的第二个 then 回调在第一个 then 函数执行完后执行,输出 p2-t2
  • 那么换个模式将外部 promise 作为 then 的返回看输入
new Promise((res) => {console.log('p1');
    res()}).then(() => {console.log('p1-t1');
    const p = new Promise((res) => {console.log('p2');
        res('inner');
    });
    p.then(() => {console.log('p2-t1');
    }).then(() => {console.log('p2-t2');
    });
    return p;
}).then((data) => {console.log('p1-t2', data)
});

// p1 -> p1-t1 -> p2 -> p2-t1 -> p2-t2 -> p1-t2 inner
  • p1 -> p1-t1 -> p2 -> p2-t1 这一段逻辑与前雷同
  • 要害是最初两个的程序,因为外部的 promise 是作为第一个 then 的返回的,所以第二个 then 的执行取决于第一个 then 被 resolve 的机会,而第一个 then 被 resolve 时,是在其外部返回的 promise 被 resolve 后的 then 里执行的
  • 也就是说外部 promise 被 resolve 后,首先外部 promise 的第一个 then 被推入 micro-task,而后第二个被推入 micro-task 的是内部 promise 第一个 then 包装后的 promise 的 res 办法,接着第三个推入 micro-task 的是,外部 promise 的第二个 then
  • 所以先输入 p2-t1,而后 resolve 内部 promise 第一个 then 返回的 promise,第二个 then 被推入 micro-task,输入 p2-t2,最初执行刚刚推入队列的 p1-t2 的输入,data 来自外部 promise 的 resolve 值
  • 留神 promise.then 链式调用返回的是最初一个 then 返回的 promise,即
new Promise((res) => {console.log('p1');
    res('innner')
}).then(() => {console.log('p1-t1');
    return new Promise((res) => {console.log('p2');
        res();}).then(() => {console.log('p2-t1');
    }).then(() => {console.log('p2-t2');
    });
}).then((data) => {console.log('p1-t2', data)
});

// p1 -> p1-t1 -> p2 -> p2-t1 -> p2-t2 -> p1-t2 undefined
  • 因为第一个 then 返回的是外部 promise 最初一个 then 生成的 promise,他没有写返回,所以是 undefined
退出移动版