zoukankan      html  css  js  c++  java
  • JS的事件循环(Event Loop)

    说明:

    Javascript是一门非阻塞单线程脚本语言;

    浏览器是多进程的,系统给它的进程分配了资源(CPU、内存),打开Chrome会有一个主进程,每打开一个Tab页就有一个独立的进程。以“从宏任务队列中取一个任务执行,再取出微任务队列中的所有任务”来分析执行代码的。

    JavaScript的任务分为同步任务和异步任务,所有的同步任务都会进入到主执行栈(形成一个执行栈execution context stack),等待任务的回调结果进入一种任务队列(task queue),直到主执行栈的任务执行完毕才会执行任务队列的异步任务,异步任务会塞入主执行栈,异步任务执行完毕后会再次进入下一个循环,整个执行过程,我们称为事件循环过程。任务队列又分为macro-task(宏任务)与micro-task(微任务),在最新标准中,它们被分别称为task与jobs。

    macro-task大概包括:

    • script(整体代码)
    • setTimeout
    • setInterval
    • setImmediate
    • I/O
    • UI render

    micro-task大概包括:

    • process.nextTick
    • Promise
    • Async/Await(实际就是promise)
    • MutationObserver(html5新特性)

    整体执行流程图:

    async/await执行顺序注意:

    输出:script start => async2 end => Promise => script end => promise1 => promise2 => async1 end => setTimeout

    分析这段代码:

    1. 执行代码,输出script start
    2. 执行async1(),会调用async2(),然后输出async2 end,此时将会保留async1函数的上下文,然后跳出async1函数。
    3. 遇到setTimeout,产生一个宏任务
    4. 执行Promise,输出Promise。遇到then,产生第一个微任务
    5. 继续执行代码,输出script end
    6. 代码逻辑执行完毕(当前宏任务执行完毕),开始执行当前宏任务产生的微任务队列,输出promise1,该微任务遇到then,产生一个新的微任务
    7. 执行产生的微任务,输出promise2,当前微任务队列执行完毕。执行权回到async1
    8. 执行await,实际上会产生一个promise返回,即 let promise_ = newPromise((resolve,reject){ resolve(undefined)})
    9. 执行完成,执行await后面的语句,输出async1 end
    10. 最后,执行下一个宏任务,即执行setTimeout,输出setTimeout

    新版的chrome浏览器中不是如上打印的,因为chrome优化了,await变得更快了,输出为:

    而await后面跟的是一个异步函数的调用,比如上面的代码,将代码改成这样:

     输出:script start => async2 end => Promise => script end => async1 end => promise1 => promise2 => async1 end setTimeout

  • 相关阅读:
    圣诞关你鸟事!
    吾属于人民,如何当家作主
    请不要做浮躁的人!
    被鬼压?
    分手后要记得做10件事情
    人生少走弯路的10条忠告
    不要一辈子靠技术生存
    跨浏览器的 inlineblock 实现[CSS]
    MVC Razor的使用
    SQL Server重温——视图、存储过程
  • 原文地址:https://www.cnblogs.com/babyfacer/p/12306026.html
Copyright © 2011-2022 走看看