promise面试题举例详解(超详细流程)

258 阅读3分钟

规则1 : 连续链式的微任务,只有第一个会进入微任务队列

规则2 : 当在then 去return时,这个return是需要去执行出终的结果值的,也就是说,如果返回的promise产生了微任务的话,会尝试从微任务队列去取出这个微任务,执行拿出结果最终结果

解析promise题目时,需要理解js事件循环的原理和js宏微任务具体是什么,然后牢记以上两条规则,否则不建议继续往下看。

new Promise((resolve, reject) => { // Promise1
  console.log("外部promise"); 
  resolve();
})
  .then(() => {
    // then1
    console.log("外部第一个then"); 
    new Promise((resolve, reject) => { // Promise2
      console.log("内部promise");  
      resolve();
    })
      .then(() => {
        // then2
        console.log("内部第一个then");
      })
      .then(() => {
        // then3
        console.log("内部第二个then");
      });
    return new Promise((resolve, reject) => {  // Promise3
      console.log("内部promise2"); 
      resolve();
    })
      .then(() => {
        // then4
        console.log("内部第一个then");
      })
      .then(() => {
        // then5
        console.log("内部第二个then2");
      });
  })
  .then(() => {
    //// then6
    console.log("外部第二个then");
  });

结合实际情况,下面给这道promise解析出答案的流程,清晰了解两条规则,并往下理解出执行流程,promise面试题都可以迎刃而解。

解析结果:

首次执行代码: 执行promise内部回调,打印外部promise,reslove()后,由于链式了then,产生了一个微任务。 我们给这个一个then 命名为 then1。

当前微任务队列: [then1]

事件循环:优先微任务 :找到 then1 ,取进主线程执行,下面是执行流程: 1、执行同步 首先 "外部第一个then" 2、 执行 then1 内部第一个promise回调,打印 "内部promise",由于链式了一个then,所以产生了一个微任务,当前微任务命名为 then2.

*当前微任务队列: [then2]

3、继续往下执行,遇到return , return是需要一个实际结果值,当前返回的是一个promise,执行同步的回调方法,打印 "内部promise2", 由于回调有一个链式then,这个then的排进微任务队列(暂且命名为 then4)

*当前微任务队列: [then2,then4]

按照2规则,return需要一个实际的值,它就会尝试从微任务队列中取出 then4执行得到 最终的结果返回。 那如此,取微任务队列的时候,按照 任务队列先进先出的逻辑,第一个就是[then2] 微任务,执行 [then2] 打印 "内部第一个then",由于then2的链式,又产生了微任务, 假命为了[then3],排进微任务队列。

** 当前微任务队列: [then4,then3]*

retuen未取到它想要的微任务,因为它需要的是then4的微任务执行结果,所以会再去微任务取。 当前在微任务队首的任务的是then4,取出来执行,由于 then4链式了一个then,假命为 [then5],

当前微任务队列: [then3,then5]。

为了给retuen 返回一个结果值,会再尝试从微任务队列中取出 [then5],按照 任务队列先进先出的逻辑,只能先取出 [then3] 执行,然后 打印"内部第二个then"。 再到 [then5],执行为 then5 打印 "内部第二个then2",返回最终结果给 reutrn。此时微任务队列空了。

4、继续往下执行,由于[then1]链接了一个then,此时又产生了一个微任务,假命为then6,

*当前微任务队列: [then6]

主线程代码再次完毕,去微任务队列检出 then6,代码执行,打印"外部第二个then"

至此结束,关键点在于promise什么时候去进微任务栈,此文章作为学习笔记记录,有问题可以评论区沟通。