MST

星途 面试题库

面试题:JavaScript Promise 状态转换与事件循环机制的关系

阐述 JavaScript 中 Promise 的状态转换与事件循环机制是如何相互影响的。例如,当一个 Promise 从 pending 转换为 resolved 时,它的回调函数是在什么阶段被放入任务队列并执行的?结合宏任务和微任务的概念进行详细解释,并通过代码示例展示其执行顺序。
41.4万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

1. Promise 的状态转换

  • Promise 有三种状态:pending(进行中)、resolved(已完成,又称fulfilled)和rejected(已拒绝)。
  • 状态只能从pending转换为resolvedrejected,且状态一旦改变,就不会再变。

2. 事件循环机制

JavaScript 是单线程语言,通过事件循环(Event Loop)机制来处理异步操作。事件循环会不断检查调用栈(Call Stack)和任务队列(Task Queue)。

  • 宏任务(Macrotask):包括script(整体代码)、setTimeoutsetIntervalsetImmediate(Node.js 环境)、I/OUI rendering等。
  • 微任务(Microtask):包括Promise.thenprocess.nextTick(Node.js 环境)、MutationObserver等。

3. Promise 状态转换与事件循环的相互影响

当一个 Promise 从pending转换为resolvedrejected时,它的.then回调函数会被放入微任务队列。事件循环机制会在当前调用栈清空后,优先处理微任务队列中的任务,处理完微任务队列后,再从宏任务队列中取出一个任务放入调用栈执行,如此循环。

4. 代码示例

console.log('start');

setTimeout(() => {
    console.log('setTimeout');
}, 0);

Promise.resolve()
   .then(() => {
        console.log('Promise.then');
    });

console.log('end');

执行顺序分析

  1. console.log('start')执行,输出start
  2. setTimeout的回调函数被放入宏任务队列。
  3. Promise.resolve().then的回调函数被放入微任务队列。
  4. console.log('end')执行,输出end
  5. 此时调用栈清空,事件循环开始处理微任务队列,Promise.then的回调函数执行,输出Promise.then
  6. 微任务队列清空,事件循环从宏任务队列中取出setTimeout的回调函数放入调用栈执行,输出setTimeout

所以最终输出顺序为:startendPromise.thensetTimeout