事件循环

什么是事件循环

JS的代码执行是基于一种事件循环的机制,之所以称作事件循环,MDN给出的解释为因为它经常被用于类似如下的方式来实现


while (queue.waitForMessage()) {
  queue.processNextMessage();
}

JS的运行环境主要有两个:浏览器、Node。

在两个环境下的Event Loop实现是不一样的,在浏览器中基于 规范 来实现,不同浏览器可能有小小区别。在Node中基于 libuv 这个库来实现

JS是单线程执行的,而基于事件循环模型,形成了基本没有阻塞(除了alert或同步XHR等操作)的状态

异步 & 同步

什么是同步?

“同步”就是后一个任务等待前一个任务结束后再去执行。

什么是异步?

“异步”与同步不同,每一个异步任务都有一个或多个回调函数。webapi 会在其相应的时机里将回调函数添加进入消息队列中,不直接执行,然后再去执行后面的任务。直至当前同步任务执行完毕后,再把消息队列中的消息添加进入执行栈进行执行。

Macrotask 与 Microtask

  • 根据 规范,每个线程都有一个事件循环(Event Loop),在浏览器中除了主要的页面执行线程 外,Web worker是在一个新的线程中运行的,所以可以将其独立看待。
  • 每个事件循环有至少一个任务队列(Task Queue,也可以称作Macrotask宏任务),各个任务队列中放置着不同来源(或者不同分类)的任务,可以让浏览器根据自己的实现来进行优先级排序以及一个微任务队列(Microtask Queue),主要用于处理一些状态的改变,UI渲染工作之前的一些必要操作(可以防止多次无意义的UI渲染)
  • 宏任务与微任务队列里的任务随着:任务进栈、出栈、任务出队、进队之间交替着进行
  • 从macrotask队列中取出一个任务处理,处理完成之后(此时执行栈应该是空的),从microtask队列中一个个按顺序取出所有任务进行处理,处理完成之后进入UI渲染后续工作
  • microtask并不是在macrotask完成之后才会触发,在回调函数之后,只要执行栈是空的,就会执行microtask。也就是说,macrotask执行期间,执行栈可能是空的(比如在冒泡事件的处理时)

宏任务

  • run
posted @ 2021-06-29 09:37  福小松  阅读(123)  评论(0编辑  收藏  举报