ske*_*tor 11 javascript async-await
我从一个我不熟悉的内部实用程序库中导入了一个函数。这个库没有文档,我只是假设它是异步的,因为它的名字getUserDetails。我以为它在做一个http请求。
我在这样的异步函数中使用它
async function getAllUserInfo(event) {
const details = await getUserDetails(event);
// other stuff
}
Run Code Online (Sandbox Code Playgroud)
我的假设是错误的。一位同事指出这不是异步的。我最终改变了它,但是当我错误地使用它时它仍然有效。我能够等待同步函数并返回正确的数据。
我的问题是关于它是如何工作的。是否在同步函数上添加 await 使其在下一个滴答声中解析,还是像同步函数那样立即返回?
Ray*_*oal 25
它有效是因为await不需要它的操作数是一个承诺!如果它不是承诺,则返回等待表达式的值。
请参阅await 运算符的文档
重要的部分是:
Run Code Online (Sandbox Code Playgroud)[rv] = await expression;
expression: APromise或任何要等待的值。rv: 返回承诺的已履行值,如果不是 ,则返回值本身Promise。
在您的情况下getUserDetails,没有返回承诺,而是一些常规用户详细信息,因此await表达式仅返回这些详细信息,就好像操作员根本不在那里一样。
但是,即使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')
Run Code Online (Sandbox Code Playgroud)
注意脚本的输出:
$ node asynctest.js
Starting the script
Starting g
In f
Finishing the script
Finishing g
Run Code Online (Sandbox Code Playgroud)
注意await调用是如何“暂停”g的,它在主块完成之前无法恢复!所以await 确实有效果。如果您没有将等待放在那里,那么您会在“完成脚本”之前看到“完成 g”。试试看!
顺便说一句,效果的原因是,即使await可以给出一个不产生承诺的表达式,JS 也会将非承诺操作数转换为立即解析为该值的承诺。所以仍然创建了一个promise,await之后的部分被视为回调,在当前执行流程完成之前不能运行。
如果您等待一个不是 Promise 的值,则会使用 将该值转换为已解决的 Promise Promise.resolve。
function sync(){
return 1
}
(async ()=>{
const v = await sync(); console.log(v)
})();
(async ()=>{
const v = await Promise.resolve(sync()); console.log(v)
})()Run Code Online (Sandbox Code Playgroud)