美文网首页技术贴
js 事件循环(Event Loop)

js 事件循环(Event Loop)

作者: zhudying | 来源:发表于2021-03-09 10:05 被阅读0次
    image
    • 执行栈

    当我们调用一个方法的时候,js会生成一个与这个方法相对应的执行环境,也叫执行上下文,这个执行环境存在着这个方法的私有作用域、参数、this对象等等。因为js是单线程的,同一时间只能执行一个方法,所以当一系列的方法被依次调用的时候,js会先解析这些方法,把其中的同步任务按照执行顺序排队到一个地方,这个地方叫做执行栈。

    • 事件队列(任务队列)

    当我们发出一个ajax请求,他并不会立刻返回结果,为了防止浏览器出现假死或者空白,主线程会把这个异步任务挂起(pending),继续执行执行栈中的其他任务,等异步任务返回结果后,js会将这个异步任务按照执行顺序,加入到与执行栈不同的另一个队列,也就是事件队列。

    1. 主线程运行的时候会生成执行栈;
    2. js从上到下解析方法,将其中的同步任务按照执行顺序排列到执行栈中;
    3. 当程序调用外部的API时,比如ajax、setTimeout等,会将此类异步任务挂起,继续执行执行栈中的任务,等异步任务返回结果后,再按照执行顺序排列到事件队列中;
    4. 主线程先将执行栈中的同步任务清空,然后检查事件队列中是否有任务,如果有,就将第一个事件对应的回调推到执行栈中执行,若在执行过程中遇到异步任务,则继续将这个异步任务排列到事件队列中。
    5. 主线程每次将执行栈清空后,就去事件队列中检查是否有任务,如果有,就每次取出一个推到执行栈中执行,这个过程是循环往复的,这个过程被称为“Event Loop 事件循环”
    • 异步任务的类型

    异步任务有两种类型:微任务(micorotask)和宏任务(macrotack)。

    1. 属于微任务的事件包括但不限于以下几种:
      Posmise.then
      MutationObserver
      process.nextTick

    2. 属于宏任务的事件包括但不限于以下几种:
      setTimeout
      setInterval
      setImmediate
      MessageChannel
      resquestAnimationFrame
      I/O
      UI交互事件

    1. 执行一个宏任务(栈中没有就从事件队列中获取)
    2. 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
    3. 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
    4. 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
    5. 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)
    • 总结
    1. js解析方法时,将同步任务排队到执行栈中,异步任务排队到事件队列中。
    2. 事件队列分为:
      宏任务:setTimeout,setInterval,setImmediate,I/O,UI交互事件
      微任务:process.nextTick,Promise.then
    3. 浏览器环境中执行方法时,先将执行栈中的任务清空,再将微任务推到执行栈中并清空,之后检查是否存在宏任务,若存在则取出一个宏任务,执行完成检查是否有微任务,以此循环…

    相关文章

      网友评论

        本文标题:js 事件循环(Event Loop)

        本文链接:https://www.haomeiwen.com/subject/rqwiaktx.html