美文网首页
略知一二之event loop(事件循环)

略知一二之event loop(事件循环)

作者: 太上云初 | 来源:发表于2018-12-28 18:31 被阅读0次

    事件循环机制


    推荐相关阅读文章


    一次完整的事件循环的过程大致可以概括为以下步骤

    • 初始状态下,js调用栈为空,微任务(micro)为空,宏任务(macro)中只有一个script脚本(整个js代码)。
    • 开始运行脚本,宏任务推入调用栈,开始执行代码。在执行代码的过程中会生成新的宏任务和微任务,他们会被推入各自的任务队列中。在脚本运行完毕后,script脚本会从宏任务队列中推出。
    • 如果在执行宏任务的过程中产生微任务,此时会继续执行微任务,直到微任务执行完毕。
    • 执行页面渲染,更新界面。
    • 检测是否存在webworker任务,如果有,则对其进行运行。

    示意图

    示意图

    自己划的重点

    • 浏览器渲染界面的时机:浏览器会在一次宏任务结束后,下一次宏任务执行前进行页面的渲染。渲染页面的时候不会执行js。
    • 在浏览器内,UI 渲染线程与 JavaScript 引擎线程为互斥的关系,当 JavaScript 引擎线程执行时 UI 渲染线程会被挂起,UI 更新会被保存在一个队列中等到 JavaScript 引擎线程空闲时立即被执行。

    Event Loop(事件循环)

    • 我们可以将整个部分分为三个部分,1、JS stack 2、Tasks(宏任务) 3、Microtasks(微任务)

    • 请看下面代码

        console.log('script start');
        setTimeout(function() {
            console.log('setTimeout');
        }, 0);
      
        Promise.resolve().then(function() {
            console.log('promise1');
        })
        console.log('script end');
      
    当上述代码开始执行时,流程如下:
    • Tasks内存有 script 脚本, script 脚本会被推入JS stack
    • 开始执行 script 脚本,期间会产生输出 script start 和 script end ,setTimeout 会推入 Tasks 中,Promise.then 会推入 Microtasks 中。
    • script 脚本执行结束后,会从 JS Stack 中推出,此时JS Stack栈内为空,Promise.then 将推入 JS stack 中,开始执行,输出 promise1 ,执行完毕后 Promise.then 从 Microtasks 中推出。
    • 此时,浏览器开始更新界面。
    • 浏览器更新完界面后,setTimeout 推入 JS Stack 栈,执行输出 setTimeout ,执行完毕后,setTimeout 从 Tasks 中推出。JS stack 内为空, Microtasks 为空。
    • 此时,更新界面

    简单来说:

    • 主线程从”任务队列”中读取事件,这个过程是循环不断的。主线程运行的时候,产生堆(heap)和栈(stack),只要栈中的代码执行完毕,主线程就会去读取”任务队列”,依次执行那些事件所对应的回调函数。

    • JS 引擎对事件队列(宏任务)与JS引擎内的任务(微任务)执行存在着先后循序,当每执行完一个事件队列的时间,JS引擎会检测内部是否有未执行的任务,如果有,将会优先执行(微任务)。


    相关文章

      网友评论

          本文标题:略知一二之event loop(事件循环)

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