最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • fucking event loop

    正文概述 掘金(不说话装高手)   2020-11-24   510

    浏览器篇

    什么是event loop

    我认为这是js单线程的一种事件调度机制,保证代码能够有序运行。 浏览器环境下,只需要知道调用堆栈call stack一个宏任务队列一个微任务队列即可。

    执行规则如下:

    1. shift第一个宏任务(也就是当前script上下文)
    let temp = 宏队列.length && 宏队列.shift()
    
    1. 将其压入栈中,并执行(包括声明函数,声明promise,赋值,运算等同步操作)
    if(temp) stack.exe(temp)
    
    1. 堆栈执行完为空,检查微任务队列并执行,
    while(微队列.length){
      let temp = 微队列.shift()
      stack.exe(temp)
    }
    
    1. 当微任务队列为空,重复第一步,此时就成了一个loop
    2. stack.exe()期间,可能会执行
    宏队列.push()
    微队列.push()
    

    event loop中的Promise

    • 浏览器环境下promise回调函数属于微任务
    • new Promise里的构造函数是同步执行的
    • then回调函数理解为注册在其promise内部
    • then回调函数只有在promise被决议后,才会推入微任务队列的末尾
    • then(xxx).then(xxx)第一个then回调函数在堆栈中执行完毕后,返回一个新的promise,值为第一个then函数的返回值(可能是同步值,可能是promise)
    • 如果第一个then返回值是promise,那第二个then函数何时被推入队列末尾,取决于这个 promise何时解决
    • 如果是非promise,那这个promise相当于Promise.resolve(),那这个then回调函数会立即推入到微任务队列末尾
    new Promise((resolve,reject)=>{
      console.log('同步执行')
      resolve(1)//将当前promise的状态设为fulfilled,值设为1(等待then函数使用)
    }).then()
    //遇到then函数,首先判断promise的状态是否解决,
    //如果解决,将 then里的回调函数添加到微任务队列的末尾
    //如果没有解决,只是注册,当状态从pending变更为解决时,再将此回调函数添加到微任务队列的末尾
    

    真题

    setTimeout(
      ()=>{console.log(0)}// push一个宏任务
    )
    
    new Promise((resolve,reject)=>{
      console.log(1)
      resolve()
    }).then(
      /*P1.then start*/
      ()=>{
        console.log(2)
        new Promise((resolve,reject)=>{
          console.log(3)
          resolve()
        }).then(
          ()=>{console.log(4)}// P3.then
        ).then(
          ()=>{console.log(5)}// P3.then.then
        )
      }
      /*P1.then end*/
     ).then(
       ()=>{console.log(6)}// P1.then.then
    )
    
    new Promise((resolve,reject)=>{
      console.log(7)
      resolve() 
    }).then(
      ()=>{console.log(8)}// P2.then
    )
    

    解答:

    • 第一个宏任务:

      1. 执行setTimeout函数,宏任务.push(()=>{console.log(0)})
      2. new Promise执行构造器函数,console.log(1)
      3. resolve() 微任务.push(P1.then)
      4. P1.then.then注册到P1.then上,等待执行
      5. 又一个new Promise执行构造器函数,console.log(7)
      6. resolve() 微任务.push(()=>{console.log(8)})
    • 第一个宏任务执行完毕,检查微任务队列 [ P1.then , ()=>{console.log(8)} ]

      1. 执行第一个微任务P1.then函数,console.log(2)
      2. new Promise执行构造器函数,console.log(3)
      3. resolve() 微任务.push(P3.then)
      4. P3.then.then注册在P3.then()上,等待执行
      5. P1.then执行完毕,返回undefined,则微任务.push(P1.then.then)
      6. 此时微任务队列[ ()=>{console.log(8)} , P3.then , P1.then.then ]
      7. 执行第一个微任务,console.log(8)
      8. 执行P3.then函数,console.log(4)
      9. P3.then函数执行完毕,返回值为undefined,微任务.push(P3.then.then)
      10. 此时微任务队列[ P1.then.then , P3.then.then ]
      11. 执行 P1.then.then函数 console.log(6)
      12. 执行 P3.then.then函数 console.log(5)
    • 微任务队列为空,开启下一轮loop

      1. 宏任务队列首个宏任务压入堆栈执行,console.log(0)

    结果

    172384650

    题目拓展

    new Promise((resolve,reject)=>{
      console.log(1)
      resolve()
    }).then(()=>{
      console.log(2)
      return new Promise((resolve,reject)=>{
        console.log(3)
        resolve()
      }).then(()=>{
        console.log(4)
      }).then(()=>{
        console.log(5)}
      )
    }).then(()=>{
      console.log(6)
    })
    

    起源地下载网 » fucking event loop

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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