【问题标题】:Why async function returns on awaiting for already resolved promise?为什么异步函数在等待已解决的承诺时返回?
【发布时间】:2019-02-28 13:17:32
【问题描述】:

确实,这样的行为可能会导致一些性能问题,即额外的上下文切换 异步函数的调用者“线程”和“延续尾部”。

async function f() {
  await Promise.resolve("something");
  console.log("f: after await");
  return "somthing_else";
}

function g() {
  const fres = f();
  console.log("g: f returns");
  fres.then((x) => console.log("finish"));
}

g();

输出是(至少在我的 Chrome 中):

g: f returns
f: after await
finish

由于 await 运算符实际上没有什么可等待的,我希望:

f: after await
g: f returns
finish

该行为是由标准指定还是取决于实现?

如果是标准行为,原因是什么?

【问题讨论】:

  • AFAIK 就像使用延迟为 0 的 setTimeout。如果您愿意,它仍然会在下一个“周期”结束,并且在当前函数完成之前不会执行。
  • Promise 回调按照规范在特殊上下文中调用。 async / await 设施不会改变这一点。因此,依赖于 Promise 完成的代码在 g() 完全完成之前无法运行。
  • @Pointy 也许你的评论应该是一个答案
  • @user396672 我正在寻找一个副本,因为我很确定几个月前有一个非常相似的问题

标签: javascript language-design


【解决方案1】:

f 函数是异步的,所以你应该在 g 函数中等待它

async function g(){
  const fres = await f();
  console.log("g: f returns");
  fres.then((x) => console.log("finish"));
}

【讨论】:

  • 据我所知,OP 希望该函数在立即解决并询问为什么不解决时表现得像非异步函数。
【解决方案2】:

Promise 被放置在一个队列中,在当前普通脚本队列为空后执行。

因此,您将完成 g() 的运行,因此在 f() 解析之前将 console.log("g: f returns"); 推送到当前堆栈。

如果日志在fres.then() 函数内,则只会在f() 解析后记录。

【讨论】:

    猜你喜欢
    • 2019-04-29
    • 1970-01-01
    • 2021-01-02
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多