8000 JS事件循环(event-loop) · Issue #29 · itboos/accumulation · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
JS事件循环(event-loop) #29
Open
@itboos

Description

@itboos

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    积累零碎知识笔记

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0