以下引号是理解微任务队列处理的主要引用:
当JS堆栈清空.时处理微任务(承诺使用)。
对我毫无意思。
事件循环的一个循环将从宏任务队列中处理一个任务(这个队列在WHATWG规范中被简单地称为任务队列)。在这个宏任务完成后,所有可用的微任务都将被处理,即在相同的执行周期内.。
现在,关于以下代码段中的第9行(**):
从执行这个代码片段w/调试器开始,在处理/执行这些.then( callback )微任务时,执行堆栈不会显示为空。
像f2()这样的常规函数是否被认为是一项任务(也称为宏任务)?(当它返回时,它是一个事件循环nextTick(),微任务队列被处理)
为什么在JS堆栈不是空的时候执行微任务?
function f2() {
let x = new Promise( (resolve, reject) => { resolve( () => {console.log('howdy')} ) })
return x
}
async function f1(){
let y = Promise.resolve().then(() => { console.log('yo1')})
console.log('yo2')
let r2awaited = await f2() //** 'yo0' and 'yo1' log when the interpreter hits this line.
return r2awaited
}
async function start(){
let y = Promise.resolve().then(() => { console.log('yo0')})
let xx = await f1()
console.log('main call return:')
console.log(xx)
}
start()
编辑:另一个奇怪的发现--当您在第17行的xx()后面添加console.log(xx)时,堆栈在执行微任务之前是完全清除的。
在微任务队列处理之前的第一步调用堆栈:

接下来的下一步。

在这两个步骤之间,处理了微任务队列。
调用堆栈是否在这些步骤^之间的遮罩下清除?
然后是否根据await [expression]之后的代码所需的词法环境创建了一个新的调用堆栈?
编辑:在发布这篇文章的时候,我不知道铬调试器调用堆栈中-(异步)-(异步)
此“假堆栈”用于异步调试,其方式与同步调试一致。
只有上面的元素-(异步)
发布于 2019-07-02 12:55:02
“当JS堆栈清空时,就会处理微任务(承诺使用)。”-Jake存档(对我来说没有意义)
“调用堆栈”是当前正在执行的内容列表:
function foo() {
debugger;
console.log('foo');
}
function bar() {
foo();
debugger;
}
bar();当我们命中第一个调试器语句时,脚本仍然在执行,就像bar和foo一样。由于存在父-子关系,所以堆栈是script > bar > foo。当我们命中第二个调试器语句时,foo已经完成执行,因此它不再在堆栈上。堆栈是script > bar。
当堆栈变为空时,将处理微任务队列,直到其为空为止。
“事件循环的一次遍历将从宏任务队列中处理一个任务(这个队列在WHATWG规范中被简单地称为任务队列)。在这个宏任务完成后,所有可用的微任务都将被处理,即在相同的回溯周期内。”
编辑:我继续阅读上面的“宏任务”作为“微任务”。浏览器中没有真正的宏任务队列,它只是一个任务队列。
虽然在处理任务后确实有一个微任务处理点,但实际上只有处理将任务排到队列中的规范,而不首先调用JS。大多数情况下,当JS堆栈清空时,微任务队列就会被清空。
当处理/执行这些.then(回调)微任务时,从执行这个代码片段w/调试器开始,执行堆栈就不会显示为空。
在执行回调时,堆栈将永远不会为空,因为回调本身将位于堆栈上。但是,如果这是堆栈上唯一的内容,则可以假设堆栈在调用此回调之前为空。
Chrome的devtools试图帮助维护一个“异步”堆栈,但这不是真正的堆栈。真正的堆栈是第一个“异步”行之前的所有内容。
像f2()这样的常规函数是否被视为一项任务?
作为一个任务或一个微任务不是函数的属性。可以在任务、微任务和事件循环的其他部分(如呈现)中调用相同的函数。例:
function foo() {}
// Here, I'll call foo() as part of the current task:
foo();
// Here, I'll let the browser call foo() in a future task:
setTimeout(foo);
// Here, I'll let the browser call foo() in a microtask:
Promise.resolve().then(foo);
// Here, I'll let the browser call foo() as part of the render steps:
requestAnimationFrame(foo);在您的示例中,在微任务中不调用f2。就像这样:
function three() {}
function two() {}
async function one() {
await two();
three();
}
one();在这里,在执行脚本的任务中调用one()。one()同步调用two(),因此它作为同一任务的一部分运行。然后,我们await调用two()的结果。因为我们是await,所以函数的其余部分在一个微任务中运行。three()被调用,因此它在同一个微任务中运行。
https://stackoverflow.com/questions/56851983
复制相似问题