关于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

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理