最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 深入理解JS执行机制

    正文概述 掘金(神奇的程序员)   2021-04-09   528

    前言

    JavaScript是一门单线程的非阻塞脚本语言,同一时刻只允许一个代码段执行。在单线程的机制下,执行异步任务时,在等待结果返回的这个时间段,后面的代码就无法执行了。

    JS在执行代码时,遇到异步任务之后还有同步任务的场景时,它并不会等待异步任务执行完,而是先执行同步任务,那么JS是如何做到这一点的呢?

    本篇文章将详细讲解上述问题,欢迎各位感兴趣的开发者阅读本文。

    事件循环

    单线程

    讲事件循环之前,我们先来理解下为什么JS不设计成多线程的。

    我们做个假设,如果JS是多线程的,因为JS有DOM API可以操作DOM,此时如果有两个线程在操作同一个DOM,线程1删除了这个dom节点,线程2要操作这个dom,就会产生矛盾,到底以哪个线程为主。

    为了避免这种情况的出现,JS就被设计成了单线程

    宏任务与微任务

    JS引擎把所有任务分为两类:宏任务、微任务。

    宏任务有:

    • script整体代码
    • setTimeout、setInterval
    • I/O
    • UI渲染
    • postMessage
    • MessageChannel
    • requestAnimationFrame
    • setImmediate(Node.js 环境)

    微任务有:

    • new Promise.then()
    • MutaionObserver
    • process.nextTick(Node.js 环境)

    执行规则

    文章一开头我们了解到了单线程的弊端,JS是通过事件循环机制(EventLoop)来解决这一弊端的,接下来我们来看下EventLoop的执行规则:

    • 所有代码作为宏任务进入主线程执行栈,开始执行
    • 执行过程中,同步代码会立即执行,宏任务进入宏任务队列,微任务进入微任务队列
    • 当前宏任务执行完成出队,读取微任务队列,有则执行,直至全部执行完毕
    • 执行浏览器ui进程渲染
    • 检查是否有webworker任务,有则执行
    • 本轮宏任务执行完成,回到第2步,继续执行,直至宏任务与微任务队列全部清空

    举例说明

    我们了解完它的执行规则后,接下来我们举个例子来说明下,如下所示:

    
    console.log("1"); // 1 同步代码:立即执行 [1]
    
    setTimeout(function() {
      console.log("2"); // 3 同步代码执行执行 输出2
      process.nextTick(function() {
        console.log("3"); // 4 进入微任务队列 [3]
      });
      new Promise(function(resolve) {
        console.log("4"); // 3 同步代码执行执行 输出4
        resolve();
      }).then(function() {
        console.log("5"); // 4 进入微任务队列 [3, 5]
      });
    });
    
    process.nextTick(function() {
      console.log("6"); // 2 进入微任务队列 [6]
    });
    
    new Promise(function(resolve) {
      console.log("7"); // 1 宏任务:立即执行 [1, 7]
      resolve();
    }).then(function() {
      console.log("8"); // 2 进入微任务队列 [6, 8]
    });
    
    setTimeout(function() {
      console.log("9"); // 5 宏任务:立即执行 [9]
      process.nextTick(function() {
        console.log("10"); // 6 进入微任务队列 [10]
      });
      new Promise(function(resolve) {
        console.log("11"); // 5 宏任务:立即执行 [9, 11]
        resolve();
      }).then(function() {
        console.log("12"); // 6 进入微任务队列 [10, 12]
      });
    });
    
    // 执行顺序:1 7 6 8 2 4 3 5 9 11 10 12
    

    我们来分析下上述代码的执行顺序,如下图所示:

    深入理解JS执行机制

    运行结果如下所示:

    深入理解JS执行机制

    代码地址

    本文为《JS原理学习》系列的第5篇文章,本系列的完整路线请移步:JS原理学习 (1) 》学习路线规划

    本系列文章的所有示例代码,请移步:js-learning

    写在最后

    至此,文章就分享完毕了。

    我是神奇的程序员,一位前端开发工程师。

    如果你对我感兴趣,请移步我的个人网站,进一步了解。

    • 文中如有错误,欢迎在评论区指正,如果这篇文章帮到了你,欢迎点赞和关注?
    • 本文首发于掘金,未经许可禁止转载?

    下载网 » 深入理解JS执行机制

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元