繁体   English   中英

等待同步函数是否同步返回值?

[英]Does awaiting a synchronous function synchronously return a value?

我从一个我不熟悉的内部实用程序库中导入了一个函数。 这个库没有文档,我只是假设它是异步的,因为它的名字是getUserDetails 我以为它在做一个http请求。

我在这样的异步函数中使用它

async function getAllUserInfo(event) {
    const details = await getUserDetails(event);
    // other stuff
}

我的假设是错误的。 一位同事指出这不是异步的。 我最终改变了它,但是当我错误地使用它时它仍然有效。 我能够等待同步函数并返回正确的数据。

我的问题是关于它是如何工作的。 是否在同步函数上添加 await 使其在下一个滴答声中解析,还是像同步函数那样立即返回?

它起作用是因为await不需要它的操作数是一个承诺! 如果它不是承诺,则返回等待表达式的值。

请参阅await 运算符的文档

重要的部分是:

 [rv] = await expression;
  • expression : 一个Promise或任何要等待的值。
  • rv :返回 promise 的已履行值,如果它不是Promise则返回值本身。

在您的情况下, getUserDetails没有返回承诺,而是一些常规用户详细信息,因此await表达式仅返回这些详细信息,就好像操作员根本不在那里一样。

但是,即使getUserDetails是同步的,在 async 函数中在它前面加上await将放弃对其调用者的控制,并且稍后选择await之后的“回调部分”。 这是一个示例脚本:

function f() {
  console.log('In f');
}

async function g() {
  console.log('Starting g');
  await f();
  console.log('Finishing g');
}

console.log('Starting the script')
g();
console.log('Finishing the script')

注意脚本的输出:

$ node asynctest.js 
Starting the script
Starting g
In f
Finishing the script
Finishing g

注意await调用如何“暂停” g,直到主块完成才能恢复! 所以await确实有效果。 如果您没有将等待放在那里,那么您会在“完成脚本”之前看到“完成 g”。 试试看!

顺便说一句,效果的原因是,即使可以给await一个不产生承诺的表达式,JS 也会将非承诺操作数转换为立即解析为该值的承诺。 所以仍然创建了一个promise,await之后的部分被视为回调,在当前执行流程完成之前不能运行。

如果您等待一个不是承诺的值,它会通过使用Promise.resolve转换为已解决的承诺。

 function sync(){ return 1 } (async ()=>{ const v = await sync(); console.log(v) })(); (async ()=>{ const v = await Promise.resolve(sync()); console.log(v) })()

暂无
暂无

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

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