Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/443.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 异步函数是否添加到调用堆栈中?_Javascript_Asynchronous_Async Await - Fatal编程技术网

Javascript 异步函数是否添加到调用堆栈中?

Javascript 异步函数是否添加到调用堆栈中?,javascript,asynchronous,async-await,Javascript,Asynchronous,Async Await,如果我声明一个如下所示的函数: function a(){ //do something } 如果我使用a()执行它,它会被放到调用堆栈的顶部,并在完成时弹出。当函数在调用堆栈中时,主线程被阻塞,在调用堆栈为空之前无法执行其他操作。 但是async函数到底会发生什么呢 b.then(function() { //do something after finish }) 如果我这样做: async function b() { //do something } 函数返回一个

如果我声明一个如下所示的函数:

function a(){
   //do something
}
如果我使用
a()
执行它,它会被放到调用堆栈的顶部,并在完成时弹出。当函数在调用堆栈中时,主线程被阻塞,在调用堆栈为空之前无法执行其他操作。 但是
async
函数到底会发生什么呢

b.then(function() {
   //do something after finish
})
如果我这样做:

async function b() {
   //do something
}
函数返回一个承诺,不阻塞主线程。这是否意味着将此函数传递给web API而不是调用堆栈?然后在完成之后,它被传递到回调函数,然后被传递到调用堆栈,这样我们就可以执行回调函数了

b.then(function() {
   //do something after finish
})

当异步函数运行的时间从调用堆栈中移出时,它会进入调用堆栈,直到函数完成或被拒绝为止。此时,它被移动到回调队列中,而所有其他同步函数都可以继续在callstack之外执行,然后当callstack为空时,事件循环会在回调队列中查找需要执行的任何其他内容。如果回调队列中有任何内容,则事件循环会将回调推入调用堆栈以执行。

是,
异步函数与普通函数一样,在执行过程中将位于调用堆栈上。您可以考虑“<代码>等待> < /COD>关键字:

function log(x) {
  console.log("at "+x);
}
function delay(t) {
  return new Promise(resolve => setTimeout(resolve, t));
}
async function example() {
  log(1);
  await delay(50);
  log(2);
  return 3;
}
function example2() {
  log(1);
  return delay(50).then(function cont() {
    log(2);
    return 3;
  })
}
example()
调用的工作原理与
example2()
调用完全相同。被调用的函数被推送到堆栈上,调用被推送到堆栈上并运行的
log(1)
,当它返回(从堆栈中弹出)时,它调用被放在堆栈上并运行的
delay(50)
,依此类推。现在,当计算
wait
运算符时,异步函数将接受操作数承诺,使用
.then()
调用附加回调,然后从
example()
调用返回函数体最终完成的承诺。因此,当它到达
await
关键字时,它会从堆栈中弹出,调用方可能会继续运行同步代码(这通常涉及使用返回的承诺执行某些操作)


然后,当承诺被解决时(在上面的示例中,当超时被命中时),作业被安排运行附加的
然后
回调。他们可能必须等待事件循环变为空闲(callstack变为空),然后当promise作业启动时,代码再次放在callstack上。在
example2
中,这是将被调用的
cont
函数,在
async函数中,它将是
示例
正文的延续,在
等待
处停止。在这两种情况下,它都会调用
log(2)
,将其推送到堆栈上并运行,当返回(从堆栈中弹出)时,将执行
return 3
语句,该语句解析承诺并从堆栈中弹出执行上下文,将其保留为空。

可能的答案,请检查您的意思是什么“传递给web API”?@Bergi我的意思是承诺传递给微任务que而不是web API。(我希望这是正确的),所以我认为异步函数也传递给微任务que?不,我猜是“web API”“这不是你想的。不,虽然promise回调是通过任务队列安排的,但当它们被执行时,它们仍然被放在调用堆栈上。“当异步函数运行时”-请更具体地说明您在这里的意思,因为当前的措辞是错误的。