promise,async,await,settimeout执行顺序

268 阅读2分钟

Promise

Promise 是一个表示异步操作最终完成或失败的对象。它有三个状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。Promise 是异步执行的,但是它的回调函数(then、catch、finally)会按照代码中的顺序放入微任务队列(microtask queue),并在当前执行栈(execution context)为空时执行。

async 和 await

async 函数是使用 async 关键字声明的函数。这样的函数返回一个 Promise 对象。await 关键字用于等待 Promise 完成,它只能在 async 函数内部使用。当 await 被调用时,它会暂停 async 函数的执行,直到 Promise 被解决或拒绝,然后继续执行 async 函数。

setTimeout

setTimeout 是一个全局函数,它用来在指定的毫秒数后执行一个函数或一段代码。setTimeout 将其回调函数放入宏任务队列(macrotask queue),在事件循环的下一个循环中执行。

执行顺序

  1. JavaScript 引擎首先执行同步代码,包括 async 函数的声明和 setTimeout 的调用。
  2. 当遇到 await 关键字时,它会异步等待 Promise 解决,并允许其他同步代码继续执行。
  3. 如果 Promise 快速解决,它的回调(如果有 await,则是 await 之后的代码)将被作为微任务添加到微任务队列中。
  4. setTimeout 的回调会在指定的时间后被添加到宏任务队列中。
  5. 当前执行栈为空时,事件循环将首先处理微任务队列中的所有微任务。
  6. 微任务队列清空后,事件循环会检查宏任务队列,并按顺序执行其中的宏任务。
console.log('script start');

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

Promise.resolve().then(function() {
  console.log('promise1');
}).then(function() {
  console.log('promise2');
});

console.log('script end');

执行结果:
script start
script end
promise1
promise2
setTimeout


解释:

  • 首先,同步代码 script start 和 script end 被打印。
  • setTimeout 的回调被添加到宏任务队列。
  • Promise 的第一个 .then() 被添加到微任务队列。
  • 当执行栈为空时,微任务队列中的 promise1 和 promise2 被执行。
  • 微任务队列清空后,事件循环处理宏任务队列中的 setTimeout 回调。

由于浏览器或JavaScript引擎的实现差异,Promise 和 setTimeout 的确切执行时机可能会有所不同。