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

标签 javascript async-await

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

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

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

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

我的问题是关于它是如何工作的。在同步函数前面加上 await 是让它在下一个滴答时解析,还是像同步函数那样立即返回?

最佳答案

之所以可行,是因为 await 不要求其操作数是一个 promise !如果它不是一个 promise ,它返回等待表达式的值。

参见 the documentation for the await operator

重要的部分是:

[rv] = await expression;
  • expression: A Promise or any value to wait for.
  • rv: Returns the fulfilled value of the promise, or the value itself if it's not a Promise.

在您的情况下,getUserDetails 没有返回 promise ,而是返回一些常规用户详细信息,因此 await 表达式只返回这些详细信息,就好像运算符(operator)没有返回一样在那里。

但是,即使 getUserDetails 是同步的,在您的异步函数中在它前面加上 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 的,它在主 block 完成之前无法恢复!所以 await 确实 有效果。如果你没有把 await 放在那里,那么你会在“完成脚本”之前看到“完成 g”。试试吧!

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

关于javascript - 等待同步函数是否同步返回值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53113281/

相关文章:

javascript - 如何正确缩放图像以适应 maxdim-by-maxdim 方形区域?

java - 在 Java 环境中编译为 javascript 的模板

javascript - 正确终止 NodeJS Async Await

c# - 执行多个数据库调用-单线程还是多线程?

javascript - 如何从ajax调用函数返回值

javascript - ng-show 用于 ng-repeat 中的特定元素

javascript - x.__proto__ == X.prototype 并不总是与 javascript 中的 x instanceof X 相同?

javascript - jQuery 简单下拉菜单

c# - 如何编写测试以公开从 using block 返回任务?

c# - 在 ASP.Net Core 3.1 中等待 SqlClient 调用的最佳方法