• JS高级学习笔记(6)- 事件循环


    参考文章:深入理解JS引擎的执行机制        JavaScript 异步、栈、事件循环、任务队列

    我的笔记:ES系列之Promise async 和 await

    Event Loop

    前提

    • js是单线程的

    • js的Event Loop是JS的执行机制,深入了解JS的执行,就等于深入了解JS里的event loop。

    问:js是为单线程的,为什么要实现异步,单线程怎么实现异步?

    答:1、js的单线程能够保证对DOM操作的顺序性,如果是多线程,A线程编辑DOM上的内容,B线程删除该DOM,那么,浏览器该怎么执行了。

    2、因为js是自上而下执行的,如果上一行解析很长时间,下面的代码解析不了,造成页面卡死。

    3、通过事件循环机制实现异步

    js的Event Loop1

    demo1

    console.log(1)
    
    setTimeout(function () {
      console.log(2)
    }, 0)
    
    console.log(3)

    执行结果:1 3 2

    首先我们知道,js将任务分为同步任务异步任务

    js的执行机制:

    判断当前执行代码是同步还是异步的,同步就进入主线程执行,异步就放到event table

    然后异步任务在event loop中注册函数,当满足条件后,就被推进event queue

    同步任务进入主线程一直执行,知道主线程空闲时,才会去event queue中查看是否有客执行的异步任务,如果有就推入主线程中。

    js的Event Loop2

    <script>
    console.log('1');
    setTimeout(function(){
      console.log('2')
    });
    
    new Promise(function(resolve){
      console.log('3');
      for(var i = 0; i < 10000; i++){
          i == 99 && resolve();
      }
    }).then(function(){
      console.log('4')
    });
    
    console.log('5');
    </script>

    按照上面的分析,执行顺序为:1 5 2 3 4;但是实际的执行顺序为:1 3 5 4 2

    这是为什么呢?

    这是因为,js将任务分为宏任务(macro-task)微任务(micro-task)

    宏任务包括:script标签、setTimeout、setInterval

    微任务包括:Promise,process.nextTick

    1. 执行到script标签进入宏任务,然后执行

    2. setTimeout为宏任务,放在任务队列中,等待该宏任务以及该宏任务中的微任务执行完毕后执行

    3. Promise准备开启微任务,但是没有开启,.then()进入微任务,等待该宏任务执行完毕后执行该微任务

    setTimeout

     setTimeout(function(){
        console.log('执行了')
     },3000)   

    我们一般说以上代码会在3s后执行,但是准确的解释是: 3秒后,setTimeout里的函数被会推入event queue,而event queue(事件队列)里的任务,只有在主线程空闲时才会执行。

    如果主线程执行了5s,那么以上代码会在5s,以及事件队列的前面的微任务执行完毕后执行。

  • 相关阅读:
    浅谈C#托管程序中的资源释放问题
    c#基本语法学习笔记
    深入剖析C#多态性
    Reporting Services API
    进程和线程的区别
    化妆品网站,饰品网站
    宠物销售网站
    卖地方特色才产品,类似湖南味道那样的网上专卖店
    建立友情链接联盟
    DIY最残忍U盘
  • 原文地址:https://www.cnblogs.com/houfee/p/10550406.html
Copyright © 2020-2023  润新知