美文网首页
事件循环简单梳理(浏览器&Nodejs)

事件循环简单梳理(浏览器&Nodejs)

作者: 一个笑点低的妹纸 | 来源:发表于2018-12-31 16:10 被阅读29次
    目录

    一、介绍

    在了解事件循环之前,首先需要了解两个概念:

    (1)调用栈和任务队列

    调用栈和任务队列关系图

    主线程运行的时候,产生堆(heap)和栈(stack),栈中的代码调用各种外部API,它们在"任务队列"中加入各种事件(click,load,done)。只要栈中的代码执行完毕,主线程就会去读取"任务队列",依次执行那些事件所对应的回调函数。—— JavaScript 运行机制详解:再谈Event Loop,阮一峰

    (2)宏任务和微任务是什么?划分的依据是什么?

    宏任务(Task/macrotask) 是严格按照时间顺序压栈和执行的,所以浏览器能够使得 JavaScript 内部任务与 DOM 任务能够有序的执行。当一个 task 执行结束后,在下一个 task 执行开始前,浏览器可以对页面进行重新渲染。

    微任务(Microtask) 通常来说就是需要在当前 task 执行结束后立即执行的任务,例如需要对一系列的任务做出回应,或者是需要异步的执行任务而又不需要分配一个新的 task,这样便可以减小一点性能的开销。

    Task:script(全局任务),事件回调,XHR回调,setTimeout,setInterval,setImmediate(node独有),I/O,UI rendering
    Microtask:更新应用程序状态的任务,包括Promise回调,MutationObserver,process.nextTick(node独有),Object.observe(废弃)

    【注意】:

    • 宏任务和微任务的执行方式在浏览器和 Node 中有差异。
    • 关于 Promise 需要注意的:promise 的 then 和 catch 才是 microtask,本身的内部代码不是。
    new Promise((resolve, reject) => {
        console.log('同步'); 
        resolve()}
    ).then(() => {
        console.log('异步');
    })
    

    Finally,什么是事件循环?

    主线程从“任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为 Event Loop(事件循环)。

    二、事件循环(浏览器)

    事件处理过程 macrotask&microtask的执行顺序

    浏览器环境下,microtask 的任务队列是每个 macrotask 执行完之后执行。

    三、事件循环(Node.js)

    JavaScript引擎作为将JavaScript解释为机器码的工具,分别运行在浏览器和Node中。而根据上下文的不同,Event loop也有不同的实现。

    Node.js体系架构

    在浏览器中,html规范定义了Event loop,具体的实现则交给不同的厂商去完成,而Node采用V8 作为js的解析引擎,在I/O处理方面使用了自己设计的libuv,libuv是一个基于事件驱动的跨平台抽象层,封装了不同操作系统一些底层特性,对外提供统一的API,事件循环机制也是它里面实现的。

    Node.js事件处理

    根据 Node.js 官方介绍,每次事件循环都包含了6个阶段,对应到 libuv 源码中的实现。
    事件循环会无限次地执行,一轮又一轮。只有异步任务的回调函数队列清空了,才会停止执行。

    Event Loop的执行顺序

    在Node.js中,microtask 会在事件循环的各个阶段之间执行,也就是一个阶段执行完毕,就会去执行 microtask 队列的任务。
    process.nextTick() 并没有在 Event Loop 的执行阶段中,而是在 Event Loop 两个阶段之间运行,根据上面说的,process.nextTick() 属于 microtask 任务类型。也就是 process.nextTick() 有可能插入在 Event Loop各个阶段中。

    关于Node定时器(process.nextTick、setTimeout、setImmediate)方面的内容,请参阅 Node 定时器详解,阮一峰

    四、参考

    相关文章

      网友评论

          本文标题:事件循环简单梳理(浏览器&Nodejs)

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