Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

JS事件循环(event-loop) #29

Open
itboos opened this issue Jul 10, 2019 · 0 comments
Open

JS事件循环(event-loop) #29

itboos opened this issue Jul 10, 2019 · 0 comments
Labels
积累 零碎知识笔记

Comments

@itboos
Copy link
Owner

itboos commented Jul 10, 2019

whatwg-event-loop规范
microtask-queue

为了协调事件、用户交互、脚本、渲染、网络等,用户代理必须使用本节中描述的事件循环。每个代理都有一个关联的事件循环,这是该代理所独有的。

macrotasks(宏任务): setTimeout ,setInterval, setImmediate,requestAnimationFram,I/O ,UI渲染

microtasks(微任务): Promise, process.nextTick, Object.observe, MutationObserver

macrotask whatwg 规范里称为 task queues, 一个 event-loop 中可能有一个或者多个 task queues ,
有一个 microtask 队列(不清楚是否只有一个), 微任务队列不是任务队列

举个🌰:

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

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

new Promise(function p1(resolve){
  console.log('p1');
  resolve();
  console.log('p1-1');
}).then(function p2(){
  console.log('p2');
});

console.log(6);
Promise.resolve().then(function p3() {
  console.log('p7')
})

// 输出:p1, p1-1, 6, p2, p7, s1, s2

image

更复杂一些的🌰:

 setTimeout(function(){
  console.log('s1');
  Promise.resolve().then(function() {
    console.log('p1')
  })
},0);

setTimeout(function(){
  console.log('s2');
  Promise.resolve().then(function() {
    console.log('p2')
  })
},0);

new Promise(function(resolve){
  console.log('p3');
  resolve();
  console.log(4);
}).then(function(){
  console.log('p4');
  Promise.resolve().then(function() {
    console.log('p5')  
  })  
});

console.log(6);
Promise.resolve().then(function() {
  console.log('p7')
})
// 输出:  p3, 4, 6, p4, p7, p5, s1, p1, s2, p2

总结:

  1. 执行主线程代码
    1.1 遇到微任务,就加到微任务队列中.
    1.2 遇到宏任务,就加到宏任务sets 中.
  2. 当js执行栈为空时, 就检查微任务队列,如果队列不为空的话,依次执行完队列里所有的微任务。否则跳到3
    2.1 当此时执行的微任务里面又 创建了微任务或者宏任务的话
    2.2 将宏任务加到宏任务队列,将微任务加到微任务队尾
    2.3 当微任务队列全部为空时,微任务执行完毕。
  3. 检测宏任务队列,如果不为空的话,取出最老的(即队头那个)那个宏任务,执行完成 ,移出队列
  4. 开始下一轮循环( 跳到1 )

(注:
Task queues are sets, not queues, because step one of the event loop processing
model grabs the first runnable task from the chosen queue, instead of dequeuing the first task.)

PS: event-loop 还是比较复杂的,规范看起来有难度(英文加涉及到的概念太多)目前没看完,后续慢慢学习。
因为 Node 里面的event-loop 实现机制不太一样,上面的解释对于Node里的event-loop不适合

参考:
从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理
difference-between-microtask-and-macrotask-within-an-event-loop-context
理解事件循环二(macrotask和microtask)

@itboos itboos added the 积累 零碎知识笔记 label Jul 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
积累 零碎知识笔记
Projects
None yet
Development

No branches or pull requests

1 participant