zoukankan      html  css  js  c++  java
  • Event Loop

    写在前面

    在 JS 引擎处理任务的过程中会碰到两种任务,分别是同步任务和异步任务。JS 引擎是单线程处理任务的,就是说在同一时间只能处理一个任务,当 JS 碰到异步任务时如果停下来一直等待异步任务执行完再进行下一步的任务,那 JS 引擎的处理效率就会大大地降低,用户体验也非常不好。

    因此,JS 引擎就将这些异步任务放到一个 “任务队列” 中,所有同步任务都放在一个 “执行栈” 中,JS 引擎在执行任务时,先将 “执行栈” 中的任务全部执行完后,此时 JS 引擎处于空闲状态,其就会去看看 “任务队列” 中有没有任务可以执行,有任务可以执行时,就将任务依次出队进行执行。

    按照上述的思路,询问查看 “任务队列” 是否有可执行的任务的事情是由 JS 做的,那 JS 是会处于一个轮询的状态。但实际上不是的,异步任务的具体可执行时间是不确定的,JS 不可能留出多余的精力给 “任务队列” 的询问查看。因此就交给了 Event Loop 去实现。

    Event Loop 会实时记录 “任务队列” 中的异步任务的信息,如异步任务中有 setTimeout 计时器的存在,Event Loop 会去计时,当时间到的时候就会将计时器对应的函数体交给 JS 引擎去执行。

    因此 Event Loop 是负责 “任务队列” 的实时运行的。

    1. Node.js 中的 Event Loop 的循环结构

    1. Timers 阶段
      setTimeout 就存放在该阶段的队列中,当轮到 Timers 阶段执行的时候,需要查看任务队列中等待的时间是否到了,若没到,就继续往下走 Event Loop。

    2. poll 阶段
      大部分时间都停留在 poll 阶段等待,其当没有任务可以执行时,只能停留在该阶段。

    3. check 阶段
      setImmediate 就是放在该阶段的队列中,当轮到 check 阶段执行的时候,该任务队列中有就立马执行,不会等待。

    process.nextTick() 不属于 Event Loop 的一部分,process.nextTick方法指定的回调函数,总是放在当前阶段的后面执行

    为什么说 setImmediate 总是比 setTimeout 先执行呢?那是因为当 Event Loop 开启的时候,事件循环就会停留在 poll 阶段,当开始执行的时候,就会从 poll 阶段开始往下执行,check 阶段在 Timers 阶段前面,所以才导致 setImmediate 总是比 setTimout 先执行。但是如果 JS 执行的时候,Event Loop 还没开启,就会从 Timers 阶段开始往下执行 Event Loop,此时的 setTimeout 就会比 setImmediate 先执行了。

    2. 浏览器中的 Event Loop 的阶段:宏任务和微任务

    2.1 MacroTask 宏任务(一会儿)包含:

    setTimeout
    setInterval
    

    2.2 MicroTask 微任务(马上)包含:

    Promise.then
    await / async
    

    当 Event Loop 中的同一阶段中既有宏任务队列,又有微任务队列时,总是先执行完微任务队列的全部任务后,再去执行宏任务队列中的任务。

    参考链接

    JavaScript 运行机制详解:再谈Event Loop

    js中的宏任务与微任务

    Event Loop、计时器、nextTick

    理解事件循环二(macrotask和microtask)

  • 相关阅读:
    一小段代码体现出的编程艺术
    2013年:第十一届软交会今天开始
    干掉baidu地图Logo的CSS
    编程语言历史,你属于几零后?
    WebServer实现SQL数据库百度坐标转换转化的算法
    使用Nginx代理Ext.net2.0异步请求报错问题
    PostgreSQL9.3新增的json_populate_recordset函数使用问题
    坐标转换服务笔录
    关于extjs中文乱码和emptyText的问题
    百度地图Polyline画直线BUG
  • 原文地址:https://www.cnblogs.com/lovevin/p/13623203.html
Copyright © 2011-2022 走看看