返回

先执行主程序还是先执行setTimeout?

前端

面试题 - JS异步执行顺序

JS是单线程的,同一时间只能有一段代码在执行,所以首先执行的就是JS的主程序。之前说主程序是宏任务,微任务优先级又比宏任务高,那为什么还先执行主程序这个宏任务呢?

## **JS异步执行顺序**

JS异步执行顺序如下:

  1. 同步任务:JS主程序是一段同步任务,会按照顺序依次执行。
  2. 宏任务:宏任务包括script标签、setTimeout、setInterval等,这些任务会放到一个队列中,按照先进先出的顺序执行。
  3. 微任务:微任务包括Promise.then、async/await、MutationObserver等,这些任务会放到另一个队列中,按照先进先出的顺序执行。

为什么先执行主程序而不是先执行setTimeout?

虽然微任务的优先级比宏任务高,但主程序是JS的入口,必须先执行主程序,才能执行后面的任务。这是因为JS是单线程的,同一时间只能执行一段代码,所以主程序必须先执行。

示例

console.log('start');

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

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

console.log('end');

这段代码的执行顺序如下:

  1. console.log('start'); // 同步任务
  2. setTimeout(() => { // 宏任务
    console.log('setTimeout');
    }, 0);
  3. Promise.then(() => { // 微任务
    console.log('Promise.then');
    });
  4. console.log('end'); // 同步任务

可以看到,主程序中的同步任务先执行,然后是setTimeout这个宏任务,最后是Promise.then这个微任务。

总结

JS异步执行顺序是先执行主程序,然后是宏任务,最后是微任务。这是因为JS是单线程的,同一时间只能执行一段代码,所以主程序必须先执行。