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
发表回复