Log*_*Wlv 9 javascript event-loop promise
在以下代码中:
setTimeout(() => console.log("hello"), 0);
Promise.resolve('Success!')
  .then(console.log)
Run Code Online (Sandbox Code Playgroud)
在我的理解中应该发生什么:
print hello直接添加到回调队列,因为时间为 0print Success!添加到回调队列如果我没记错的话,回调队列是FIFO。
但是代码输出是:
Success!
hello
Run Code Online (Sandbox Code Playgroud)
解释是什么?
zhu*_*ien 11
有 2 个单独的队列用于处理回调。一个宏队列和一个微队列。setTimeout将宏队列中的项目排入队列,同时承诺解析 - 到微队列。当前正在执行的宏任务(在这种情况下是主脚本本身)是同步执行的,一行一行,直到它完成。完成后,循环执行微任务队列中排队的所有内容,然后继续执行宏队列中的下一项(在您的情况下是从 中console.log("hello")排队的setTimeout)。
基本上,流程如下所示:
宏任务队列:[],微任务队列:[]。
setTimeout(() => console.log("hello"), 0); 遇到导致在宏任务队列中推送新项目的情况。宏任务队列:[ console.log("hello")],微任务队列:[]。
Promise.resolve('Success!').then(console.log)已读。PromiseSuccess!立即解析为,并且console.log回调被排入微任务队列。宏任务队列:[ console.log("hello")],微任务队列:[ console.log('Success!')]。
console.log('Success!') 从微任务队列中拉出并执行。宏任务队列:[ console.log("hello")],微任务队列:[]。
console.log("hello")。宏任务队列:[],微任务队列:[]。
console.log("hello"),它会再次检查微任务队列中是否有任何内容。它是空的,所以它检查宏任务队列。它也是空的,所以所有排队的东西都被执行并且脚本完成。不过,这是一个简化的解释,因为它可能会变得更加棘手。微任务队列通常主要处理 promise 回调,但您可以自己将代码排入队列。微任务队列中新添加的项目仍然会在下一个宏任务项目之前执行。此外,微任务可以将其他微任务排入队列,这可能导致处理微任务的无限循环。
一些有用的参考资源:
这里涉及两个不同的队列:任务队列和微任务队列。
使用调度的回调函数setTimeout添加到任务队列中,而使用Promise调度的回调添加到微任务队列或作业队列中。
处理一个微任务队列:
另请注意,如果微任务队列中的微任务将另一个微任务排队,则该微任务也将在处理任务队列中的任何内容之前进行处理。换句话说,在处理任务队列中的下一个任务之前,微任务队列将被处理直到其为空。
以下代码片段显示了一个示例:
setTimeout(() => console.log('hello'), 0);
Promise.resolve('first microtask')
  .then(res => {
    console.log(res);
    return 'second microtask';
  })
  .then(console.log);Run Code Online (Sandbox Code Playgroud)
在您的代码中,回调函数setTimeout被添加到任务队列中,并将Promise.resolve微任务排队到微任务队列中。该队列在脚本执行结束时进行处理。这就是为什么在“hello”之前记录“success”。
下图显示了代码的逐步执行:
进一步阅读的资源:
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           733 次  |  
        
|   最近记录:  |