Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

精读《Tasks, microtasks, queues and schedules》 #264

Closed
ascoders opened this issue Aug 15, 2020 · 6 comments
Closed

精读《Tasks, microtasks, queues and schedules》 #264

ascoders opened this issue Aug 15, 2020 · 6 comments

Comments

@ascoders
Copy link
Owner

ascoders commented Aug 15, 2020

Chrome 员工写了一篇介绍任务队列的文章:Tasks, microtasks, queues and schedules 读完后觉得彻底理解了队列,同时对各浏览器实现不统一也感到略为沮丧,尽量不要让业务逻辑强依赖队列执行规则,说不定在某个实现有 bug 的浏览器上导致严重故障。


精读《Tasks, microtasks, queues and schedules》

@lamysafari
Copy link

console.log('timeout') 入栈 Tasks。
console.log('promise') 入栈 microtasks。

这里应该是进入队列而不是入栈吧?

@giscafer
Copy link
Contributor

@lamysafari 队列要执行的时候也会到执行栈中,可能差不多

@giscafer
Copy link
Contributor

giscafer commented Aug 25, 2020

@ascoders

MutationObserver 由于还没调用,因此这次 outer.setAttribute('data-random') 的改动实际上没有作用。

这句话描述有误,outer.setAttribute('data-random') 其实是正常调用了的,可以通过 console.log(outer.getAttribute('data-random')); 打野就知道改变了属性了的。

mutate 属性只有一次输出,是因为第一个 Mutation observers 已经进入了pedding待执行的阶段,所以不会重新新增一个 mutation 的微任务吧。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>点击冒泡 + 任务</title>
  </head>
  <style>
    div {
      height: 200px;
    }
    .inner {
      width: 400px;
      background-color: blue;
    }
    .outer {
      width: 600px;
      background-color: red;
    }
  </style>
  <body>
    <div class="outer">
      <div class="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', outer.getAttribute('data-random'));
      }).observe(outer, {
        attributes: true,
      });

      // Here's a click listener…
      function onClick(event) {
        console.log('click');

        setTimeout(function () {
          console.log('timeout');
        }, 0);

        Promise.resolve().then(function () {
          console.log('promise');
        });

        outer.setAttribute('data-random', Math.random());
        console.log(
          event.currentTarget.className,
          outer.getAttribute('data-random')
        );
      }

      // …which we'll attach to both elements
      inner.addEventListener('click', onClick);
      outer.addEventListener('click', onClick);

      inner.click();
    </script>
  </body>
</html>

输出结果

click
inner 0.9825763359570798
click
outer 0.7745236852004302  // 
promise
mutate 0.7745236852004302  // 第二次改变的属性
promise
timeout
timeout

@ascoders
Copy link
Owner Author

@giscafer 嗯,你说的比较准确,setAttribute 有作用,但这个场景下对 MutationObserver 没有实际作用。

@waitingsong
Copy link

的确,实践中应该避免业务逻辑强依赖队列执行顺序,或者说对于异步请求应该通通作为无序队列处理。

@oakland
Copy link

oakland commented Dec 8, 2020

这篇文章写的时候还没有 async/await,无法全面的学习到现在 js 语言层面中的 event loop / micro task 全貌。

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants