美文网首页
macrotask与microtask

macrotask与microtask

作者: 菊花泡茶 | 来源:发表于2020-07-01 10:27 被阅读0次

    浏览器环境

    注意点

    首先,

    一个浏览器环境,只能有一个事件循环 event loops

    而一个事件循环可以多个任务队列 task queue

    每个任务都有一个任务源 task source

    其次,

    每个 macro task 结束后,都要清空所有的 micro task

    总的来说,

    整体代码(script)是一个macrotask

    执行过程中,setTimeout是一个macrotask,因此会创建新的macrotask,还会创建microtask,两个任务分别挂起(promise 构造函数因为是同步的)

    浏览器执行microtask,将microtask queue所有任务取出

    再执行一个macrotask,将microtask queue下一个任务取出

    最终所有队列空,执行完毕

    Vue $nextTick

    Vue中的$nextTick也运用宏任务,微任务进行DOM更新

    观察到数据变化时会缓冲所有改变(不重复),通过Promise.then / MessageChannel / setTimeout(0)(不支持采用后者)将watcher事件放入任务队列

    在每次查找异步队列并推入执行栈后,执行$nextTick

    注意 mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick 替换掉 mounted

    https://segmentfault.com/a/1190000012861862

    https://www.zhihu.com/question/36972010

    加深理解

    https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    <body>
      <div class="outer">outer
        <div class="inner">inner</div>
      </div>
      <script >
        // Let's get hold of those elements
        var outer = document.querySelector('.outer');
        var inner = document.querySelector('.inner');
        
        // Let's listen for attribute changes on the
        // outer element
        new MutationObserver(function () {
          console.log('mutate');
        }).observe(outer, {
          attributes: true,
        });
        
        // Here's a click listener…
        function onClick() {
          console.log('click');
        
          setTimeout(function () {
            console.log('timeout');
          }, 0);
        
          Promise.resolve().then(function () {
            console.log('promise');
          });
        
          outer.setAttribute('data-random', Math.random());
        }
        
        // …which we'll attach to both elements
        inner.addEventListener('click', onClick);
        outer.addEventListener('click', onClick);
        // 两种情况
        inner.click()
      </script>
    
      <style>
        .outer {
          width: 100px;
          height: 100px;
          background-color: green;
        }
        .inner {
          width: 50px;
          height: 50px;
          background-color: yellow;
        }
      </style>
    </body>
    </html>
    
    /*
    手动交互:
    click
    promise
    mutate
    click
    promise
    mutate
    timeout
    timeout
    
    click(): (JS stack中有script,不执行微任务;Microtasks存在Mutation observers等待,不能添加)
    click
    click
    promise
    mutate
    promise
    timeout
    timeout
    */
    

    相关文章

      网友评论

          本文标题:macrotask与microtask

          本文链接:https://www.haomeiwen.com/subject/spccqktx.html