JavaScript事件循环 (简单理解)

73 阅读2分钟

JavaScript事件循环

JavaScript中任务可以分为同步任务和异步任务

异步任务又分为宏认为和微任务

  • ES5之后,JavaScript引入了Promise,现在不需要浏览器,JavaScript引擎也能够发起异步任务了

宏任务是由宿主发起的(浏览器、Node)

微任务是由JavaScript引擎发起的

  • Promise本身同步,then/catch的回调函数是异步的

宏任务、微任务执行过程

代码可能有三种:

  1. 同步代码 ,由 Js执行栈/回调栈执行

  2. 微任务的异步代码,由Js引擎执行,会优先执行

    • process.nextTick #Node
    • Promist.then().catch()
    • Async/Await
    • Object.observe
    • ...
  3. 宏任务 由宿主环境执行

    • script代码块
    • setTimeout/ setInterval定时器
    • setImmediate定时器
    • I/O

宏任务、微任务-执行过程顺序

  1. 同步代码
  2. 为任务的异步代码(Promise等)
  3. 宏任务的异步代码(定时器等)

执行栈、宏任务队列、微任务队列

完整的执行过程:

  1. 首先执行执行栈里的同步代码,执行完毕之后,去微任务队列中检查是否有任务,
  2. 有的话根据队列的特性 先进先出,拿到微任务队列里的任务,通过事件循环推到执行栈中执行,重复执行此步骤到微任务队列结束
  3. 最后去宏任务队列,也是先进先出,通过事件循环推到执行栈中执行,但是执行完每一个宏任务的时候,会去检查微任务队列,如果有新添加进来的微任务队列就优先执行第二步,直到微任务队列清空后才会执行下一个微任务
console.log(1);  //同步任务
setTimeout(function(){  //宏任务
    console.log(2);
},200);
const task = new Promise((resolve,reject)=>{ 
    console.log(3); //同步任务
    resolve(4); //
    console.log(5); //同步任务
});
​
task.then(data=>{ //异步任务中的微任务
    console.log(data); 
})
​
console.log(6); //同步任务/** output
 1
 3
 5
 6
 4
 2
*/

最后补充一点,Promise中的reject和resolve是不能终止代码执行,需要自己return,所以5会被打印出来

有错误的地方欢迎大佬指正!