共计 2132 个字符,预计需要花费 6 分钟才能阅读完成。
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
正文完
发表至: javascript
2020-11-11