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

理解 Event Loop #16

Open
bigggge opened this issue Apr 16, 2018 · 0 comments
Open

理解 Event Loop #16

bigggge opened this issue Apr 16, 2018 · 0 comments
Labels

Comments

@bigggge
Copy link
Member

bigggge commented Apr 16, 2018

JavaScript 是一门单线程语言 (JS多线程能力),但是其事件循环的特性使我们可以异步地执行程序。先看一段代码,试想它会以何种顺序输出?

console.log(1)

setTimeout(() => {
  console.log(2)
}, 0)

Promise.resolve().then(() => {
	console.log(3)
}).then(() => {
	console.log(4)
})

console.log(5)

大部分浏览器会输入以下内容 1、5、3、4、2

要理解上面代码的输出原理,你就需要了解 JavaScript 的 event loop 是如何处理 tasks 以及 microtasks

macrotask(task,宏任务) 与 microtask(job,微任务)

ECMAScript 规范并没有提及 Event Loop。Event Loop 是定义在 HTML规范 中。Promises/A+ 规范ECMAScript 规范 也有相关内容。

一个事件循环 (Event Loop) 会有一个或多个任务队列 (task queue,又称 task source),这里的 task queue 就是 macrotask queue,而 Event Loop 仅有一个 microtask queue。每个线程都有一个独立的 Event Loop,所以每个 web worker 也有独立的 Event Loop

macrotask 是严格按照时间顺序压栈和执行的。当一个 task 执行结束后,在下一个 task 执行开始前,浏览器可以对页面进行重新渲染。主要包含:setTimeout,setInterval,setImmediate,I/O,UI交互事件

microtask 通常来说就是需要在当前 task 执行结束后立即执行的任务。主要包含:Promise的回调函数,MutaionObserver

最基本的 Event Loop 如图所示:

  • queue 用于存储需要执行的函数
  • Event Loop 执行一次,从 macrotask 队列中拉出一个 task 执行
  • Event Loop 继续检查 microtask 队列是否为空,依次执行直至清空队列

Node

加上 process.nextTick ,看看会是什么结果?

console.log(1);

setTimeout(() => {
  console.log(2);
  new Promise(resolve => {
    console.log(4);
    resolve();
  }).then(() => {
    console.log(5);
  });
  process.nextTick(() => {
    console.log(3);
  });
});

new Promise(resolve => {
  console.log(7);
  resolve();
}).then(() => {
  console.log(8);
});

process.nextTick(() => {
  console.log(6);
});

输入 1、7、6、8、2、4、3、5

原因是:优先清空 next tick queue,即通过 process.nextTick 注册的函数,再清空 other queue,如 Promise

参考资料:

Event Loop的规范和实现

这一次,彻底弄懂 JavaScript 执行机制

深入理解 JavaScript 事件循环(二)— task and microtask

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