【JavaScript】一文详解事件循环机制

目录

一、是什么

二、同步任务和异步任务

三、宏任务和微任务

小结:微任务是跟屁虫,一直跟着当前宏任务后面代码执行到一个微任务就跟上,一个接着一个。

例子理解:

五、题目巩固

六、总结


一、是什么

首先JavaScript是一种单线程语言,同一时间内只能做一件事情,所有的任务都需要排队完成。这并不意味着单线程就是阻塞,而实现单线程非阻塞的方法就是事件循环。

为什么JavaScript不能有多个线程呢?

        作为浏览器脚本语言,JavaScript的主要用途是与用户互动以及操作dom节点。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,当JavaScript同时有两个线程,一个是在A节点上添加内容,另一个是删除A节点,这个时候浏览器不知道应该以哪个为准。

        为了避免这种复杂性,因此JavaScript只能是单线程。

二、同步任务和异步任务

JavaScript中,所有的任务都可以分为

  • 同步任务:立即执行的任务,同步任务一般会直接进入到主线程中执行
  • 异步任务:异步执行的任务,比如ajax网络请求,setTimeout定时函数等

同步任务进入主线程,即主执行栈,异步任务进入任务队列,主线程内的任务执行完毕为空,会去任务队列读取对应的任务,推入主线程执行。

三、宏任务和微任务

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

常见的宏任务:

  • script(整体代码)
  • setTimeout
  • setInterval
  • postMessage、MessageChannel
  • setImmediate、I/O(Node.js)
  • UI交互事件
  • ajax请求

常见的微任务:

  • Promise.then

  • MutaionObserver

  • process.nextTick(Node.js)

任务的优先级: process.nextTick > promise.then > setTimeout > setlmmediate

【JavaScript】一文详解事件循环机制_第1张图片

【JavaScript】一文详解事件循环机制_第2张图片

小结:微任务是跟屁虫,一直跟着当前宏任务后面代码执行到一个微任务就跟上,一个接着一个。

例子理解:

【JavaScript】一文详解事件循环机制_第3张图片

五、题目巩固

console.log(1)

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

new Promise((resolve, reject)=>{
    console.log('new Promise')
    resolve()
}).then(()=>{
    console.log('then')
})

console.log(3)

 流程如下:

// 遇到 console.log(1) ,直接打印 1
// 遇到定时器,属于新的宏任务,留着后面执行
// 遇到 new Promise,这个是直接执行的,打印 'new Promise'
// .then 属于微任务,放入微任务队列,后面再执行
// 遇到 console.log(3) 直接打印 3
// 好了本轮宏任务执行完毕,现在去微任务列表查看是否有微任务,发现 .then 的回调,执行它,打印 'then'
// 当一次宏任务执行完,再去执行新的宏任务,这里就剩一个定时器的宏任务了,执行它,打印 2

六、总结

事件的循环机制规定了执行代码的顺序

  1. 先执行同步代码;
  2. 遇到异步宏任务则将异步宏任务放进宏任务队列中;
  3. 遇到异步微任务则将异步微任务放进微任务队列中;
  4. 当script整体代码所有同步代码执行完毕后,再将异步微任务从【任务队列】中调入【主线程】执行;
  5. 微任务执行完毕后再将异步宏任务从【任务队列】中调入【主线程】执行;微任务再跟着当前宏任务后面,代码执行到一个微任务就跟上,一个接着一个。
  6. 一直循环到所有任务执行完毕。

你可能感兴趣的:(javascript,开发语言,前端)