简体   繁体   English

Promise 是否将回调函数添加到微任务队列?

[英]Does Promise add the call backfunction to microtask queue?

I read some files about the microtask and macrotask queue.我读了一些关于微任务和宏任务队列的文件。 I know that the callback function of a resolved promise is added to the microtask, same as the other sync tasks.我知道已将已解析 promise 的回调 function 添加到微任务中,与其他同步任务相同。 But the following code:但是下面的代码:

fetch=() => new Promise ((resolve) => resolve ({m: 121}))

function x() {
    let d = 3;
    fetch().then((data) => {
        d += data.m;
        console.log("b", d);
     });
    console.log("a", d);
 }

 x();

gives a result of给出的结果

a 3
b 124

IAs I thought, since fetch here fetches a "local" file and it takes no time, so the callback function is immediately added to the microtask queue, and then console.log("a", d);我想,既然 fetch 在这里获取一个“本地”文件,并且不需要任何时间,所以回调 function 立即添加到微任务队列中,然后console.log("a", d); is added to the microtask queue.被添加到微任务队列中。 If so, the result should be如果是这样,结果应该是

b 124
a 124

So what is the reason for the real result?那么真实结果的原因是什么呢? Why the call back function is executed after console.log("a", d);为什么回调 function 在console.log("a", d);之后执行? ?

Whether or not a callback is added to the microtask queue or the callback queue has nothing to do with how long it takes to run.微任务队列中是否添加回调或回调队列与运行时间无关。 The Promise callbacks are always added to the microtask queue. Promise回调总是添加到微任务队列中。 Regardless of how long it takes.不管需要多长时间。 And, the queue is cleared, after the call stack is empty.并且,在调用堆栈为空后,队列被清除。 In your example, the function x has to complete execution before your Promise callback can run.在您的示例中, function x必须在您的Promise回调可以运行之前完成执行。 So, a is logged first.因此,首先记录a

Read more about the event loop here . 在此处阅读有关事件循环的更多信息。 But in a nutshell, browser API callbacks go in the callback queue, and higher priority callbacks like the Promise callbacks go in the microtask queue. But in a nutshell, browser API callbacks go in the callback queue, and higher priority callbacks like the Promise callbacks go in the microtask queue. The queues are cleared only after the call stack is empty.只有在调用堆栈为空后,队列才会被清除。

This can lead to puzzling behaviors like the following code running forever since the call stack never becomes empty.这可能会导致令人费解的行为,例如以下代码永远运行,因为调用堆栈永远不会变空。

let flag = true;
setTimeout(() => flag = false, 200)
while (flag) console.log('hello')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM