美文网首页
JS中的事件循环机制(Event Loop)

JS中的事件循环机制(Event Loop)

作者: 她是我的bug | 来源:发表于2018-12-27 10:13 被阅读0次

    前言

    众所周知,JavaScript是一门单线程语言,虽然在html5中提出了web-worker,但这并未改变JavaScript是单线程这一核心。

    为了协调事件、用户交互、脚本、UI渲染和网络处理等行为,用户引擎必须使用 Event Loops。Event Loop包含两大类:一类是基于Browsing content,一种是基于Worker,二者是独立运行的。

    任务队列

    所有的任务可以分为同步任务和异步任务,同步任务,顾名思义,就是立即执行的任务,同步任务一般直接进入到主线程中执行。二异步任务,比如ajax请求,setTimeout定时器函数等都属于异步任务,异步任务会通过任务队列(Event Queue)的机制来进行协调


    同步任务和异步任务分别进入到不同的执行环境,同步进入主线程,即主执行栈,异步进入 Event Queue。主线程内的任务执行完毕为空,回去 Event Queue 读取对应的任务,推入主栈中执行。

    上述过程的不断重复就是我们说的Event Loop(事件循环)。
    在事件循环中,每进行一次循环操作称为tick,每一次tick的任务处理模型是比较复杂的,其关键的步骤可以总结如下:

    1. 在此次tick中选择最先进入队列的任务(oldest task),如果有则执行(一次)
    2. 检查是否存在Microtasks,如果存在则不停地执行,直至清空Microtask Queue
    3. 更新render
    4. 主线程重复执行上述步骤

    可以用一张图来说明下流程:



    这里相信有人会想问,什么是microtasks?规范中规定,task分为两大类, 分别是Macro Task (宏任务)和Micro Task(微任务), 并且每个宏任务结束后, 都要清空所有的微任务,这里的Macro Task也是我们常说的task,有些文章并没有对其做区分,后面文章中所提及的task皆看做宏任务(macro task)。

    (macro)task主要包含:script(整体代码)、setTimeout、setInterval、I/O、UI交互事件、setImmediate(Node.js 环境)

    microtask主要包含:Promise、MutaionObserver、process.nextTick(Node.js 环境)

    setTimeout/Promise等API便是任务源,而进入任务队列的是由他们指定的具体执行任务。来自不同任务源的任务会进入到不同的任务队列。其中setTimeout与setInterval是同源的。

    参考

    相关文章

      网友评论

          本文标题:JS中的事件循环机制(Event Loop)

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