我从一个我不熟悉的内部实用程序库中导入了一个函数。这个库没有文档,我只是假设它是异步的,因为它的名称是getUserDetails
。我以为它在做http请求。
我在类似的异步函数中使用了它
async function getAllUserInfo(event) {
const details = await getUserDetails(event);
// other stuff
}
我的假设是错误的。一位同事指出,is不是异步的。我最终更改了它,但当我使用错误时,它仍然有效。我能够等待一个同步函数,它返回了正确的数据。
我的问题是关于它是如何运作的。在同步函数上准备等待是否会使其在下一个刻度上解析,还是像同步函数应该的那样立即返回?
它之所以工作,是因为await
不要求其操作数为promise!如果不是promise,则返回等待的表达式的值。
请参阅等待操作员的文档
重要的部分是:
[rv] = await expression;
expression
:Promise
或任何要等待的值rv
:返回promise的已实现值,如果不是Promise
,则返回值本身
在您的案例中,getUserDetails
没有返回promise,而是返回一些常规用户详细信息,因此await
表达式只是返回了这些详细信息,就好像根本不存在运算符一样。
然而,即使getUserDetails
是同步的,在异步函数中用await
对其进行预处理也会将控制权交给其调用者,并且;回叫部分";在稍后拾取CCD_ 11之后。下面是一个示例脚本:
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
注意CCD_ 12如何调用";暂停";g、 直到主块结束,它才能够恢复!因此await
确实有的作用。如果你没有把等待放在那里,那么你会看到";精加工g〃;在";正在完成脚本";。试试看!
顺便说一句,产生这种效果的原因是,即使可以给await
一个不产生promise的表达式,JS也会将非promise操作数转换为立即解析为该值的promise。因此,promise仍然被创建,等待之后的部分被视为回调,在当前执行流完成之前无法运行。
如果等待的值不是promise,则会使用Promise.resolve
将其转换为已解析的promise。
function sync(){
return 1
}
(async ()=>{
const v = await sync(); console.log(v)
})();
(async ()=>{
const v = await Promise.resolve(sync()); console.log(v)
})()