Promise执行顺序解析与面试题解答

需积分: 0 0 下载量 174 浏览量 更新于2024-08-03 收藏 3KB MD 举报
"这篇文档是关于前端面试中对Promise理解的考察,主要讲解了Promise的调用顺序和异步执行的原理。" 在前端开发中,Promise是处理异步操作的重要工具,它允许我们优雅地处理异步代码,避免了回调地狱。在面试中,对Promise的理解和使用能力是评估前端程序员技能的重要方面。本题主要考察的是Promise的执行顺序以及其内部的事件循环和任务队列机制。 题目中的代码如下: ```js Promise.resolve().then(() => { console.log(0); return Promise.resolve(4); }).then((res) => { console.log(res); }); Promise.resolve().then(() => { console.log(1); }).then(() => { console.log(2); }).then(() => { console.log(3); }).then(() => { console.log(5); }).then(() => { console.log(6); }); ``` 这段代码中,有两个Promise链。首先,第一个Promise链在输出0之后,返回了一个新的Promise,该Promise在后续的then中输出4。第二个Promise链则依次输出1、2、3、5、6。 对于Promise的执行,关键在于理解JavaScript的事件循环(Event Loop)和任务队列(Task Queue)。JavaScript引擎是单线程的,但通过事件循环和任务队列,它可以处理异步任务。任务队列分为宏任务(Macro Task)和微任务(Micro Task)。 在每次事件循环中,JavaScript会先执行一个宏任务,然后在当前宏任务执行完毕后,会清空所有微任务。在下一个宏任务开始之前,所有微任务都会被执行。Promise的then方法创建的回调函数会被放入微任务队列。 在这个例子中,第一个Promise链的两个then分别属于两个微任务,它们会在当前宏任务结束后立即执行。因此,输出顺序是0、4。第二个Promise链则构成了一条连续的微任务链,它们在当前宏任务的末尾一起执行,所以输出顺序是1、2、3、5、6。 再来看一道关于Promise交替执行的题目: ```js Promise.resolve().then(() => { console.log(1); }).then(() => { console.log(2); }).then(() => { console.log(3); }).then(() => { console.log(4); }); Promise.resolve().then(() => { console.log(10); }).then(() => { console.log(20); }).then(() => { console.log(30); }).then(() => { console.log(40); }); Promise.resolve().then(() => { console.log(100); }).then(() => { console.log(200); }).then(() => { console.log(300); }).then(() => { console.log(400); }); ``` 在这个例子中,每个Promise链都是独立的,它们的then方法会在各自的微任务队列中等待执行。由于微任务会交替执行,所以输出会是这样的顺序:1、10、100、2、20、200、3、30、300、4、40、400。这种交替执行是编译器为了防止一个Promise持续占据事件而做的优化。 最后,提到了当then返回一个新的Promise时,这相当于在当前微任务结束时添加了额外的任务。这意味着,如果then内部有异步操作,返回的新Promise的then将会在当前微任务结束后的下一个微任务中执行。 理解和掌握Promise的执行顺序以及事件循环机制是前端开发者必备的技能,这不仅有助于编写出更清晰的异步代码,也是面试中常被考察的知识点。