function f() {
console.log("A");
setTimeout(() => console.log("F"))
new Promise((resolve, reject) => {
console.log("B");
resolve();
console.log("C");
}).then(() => console.log("E"));
console.log("D");
}
f();
输出结果为:
A
B
C
D
E
F
setTimeout
那一块比较好理解,其实就是Event Loop
,但是 Promise
不是很了解,有没有大佬能解释一下,Promise 内部究竟是如何运作的?为什么是先E再F?
Promise
和setTimeout
进的是不同的队列,假设Promise
进的队列 A,setTimeout
进的队列 B, A 的优先级要大于 B, 只有 A 执行完之后才会执行 B, 当new Promise
执行完之后,因为后面跟着then
,会把后面的then
的回调推入 A ,然后执行刚刚推入 A 的回调,等执行完了,最后执行 B 里面的setTimeout
你可以看看后面的这个文章,里面的演示很形象
Tasks, microtasks, queues and schedules
补充
上面的队列 A 就是
microtask
, 队列 B 就是macrotask
. 他们都属于异步任务, 区别是microtask
优先于macrotask
,并且每次时间循环中,macrotask
只会提取一个执行, 而microtask
会一直提取,知道microtask
队列清空.如果then "E"
后面还跟着then
,那么还是会执行后面的then
,最后才会执行到setTimeout
更详细的内容可以查看下面的这篇文章
理解 JavaScript 中的 macrotask 和 microtask
再次补充
之后在测试的时候发现一个问题,下面的代码在
node
和chrome
执行结果不一致.如果按照每次
macrotask
只拉取一个任务执行的话,那node
的输出是什么鬼.抱着这个疑问,继续翻文章
原因是因为
chrome
和node
的关于Event-Loop
的实现不同详细的解释可以看知乎的这个回答 Promise在node和chrome下表现为什么会有差异?
参考