返回

JavaScript 代码执行顺序剖析,面试必备!

前端

序言

最近写了一些异步递归的代码,着实有点头疼,索性重新研究一下JavaScript 代码执行顺序,并附上一道面试题的解析。

JavaScript 代码执行顺序

微任务优先级高于宏任务的前提是:同步代码已经执行完成。因为 script 属于宏任务,程序开始后会首先执行所有同步代码,然后执行微任务队列中的任务,再执行宏任务队列中的任务。

同步任务

同步任务是指在主线程上执行的任务,它会阻塞后续任务的执行。常见的同步任务包括:

  • 变量声明
  • 函数定义
  • 函数调用
  • 条件语句
  • 循环语句

异步任务

异步任务是指不在主线程上执行的任务,它不会阻塞后续任务的执行。常见的异步任务包括:

  • setTimeout
  • setInterval
  • AJAX 请求
  • 事件监听器

微任务

微任务是指在事件循环中执行的任务,但优先级高于宏任务。常见的微任务包括:

  • Promise.then()
  • MutationObserver
  • process.nextTick()

事件循环

事件循环是一个不断重复的过程,它负责执行任务队列中的任务。事件循环的工作原理如下:

  1. 首先,事件循环会检查是否有同步任务需要执行,如果有,则执行所有同步任务。
  2. 然后,事件循环会检查是否有微任务需要执行,如果有,则执行所有微任务。
  3. 最后,事件循环会检查是否有宏任务需要执行,如果有,则执行所有宏任务。
  4. 事件循环会重复上述步骤,直到所有任务都执行完成。

面试题解析

有一段 JavaScript 代码如下:

console.log('script start');

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

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

console.log('script end');

请问这段代码的输出是什么?

答案是:

script start
script end
promise1
setTimeout

解析

  1. 首先,事件循环会执行同步代码,因此会输出 script startscript end
  2. 然后,事件循环会检查是否有微任务需要执行,发现有 Promise.resolve().then(() => {console.log('promise1');}),于是执行它,输出 promise1
  3. 最后,事件循环会检查是否有宏任务需要执行,发现有 setTimeout(() => {console.log('setTimeout');}, 0);,于是执行它,输出 setTimeout

结语

以上就是 JavaScript 代码执行顺序的剖析,希望对你有帮助。如果你还有其他问题,欢迎在评论区留言。