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

  • 相关阅读:
    使用简单的反射技术重构组合查询串功能
    沤血分享之:使用Opera浏览器技巧全集
    项目中用到的RE分析
    关于调用新浪微博与腾讯微博
    正则 (?i,m,s,x,g)
    求职路 第二章 深圳篇
    12320平台架构及部署
    网站会员密码
    求职路 第二章 技术篇
    TFS故障一二
  • 原文地址:https://www.cnblogs.com/babyfacer/p/12306026.html
Copyright © 2011-2022 走看看