【发布时间】:2021-05-14 14:37:03
【问题描述】:
如果可以通过函数代码中的await关键字自动确定,为什么我每次都要在每个异步函数之前写async关键字?
function foo() { // This function is sync because it has no await keyword.
return new Promise(function(resolve)
{
setTimeout(function(){resolve("RESULT")},1000)
})
}
function bar() { // This function is sync because it has no await keyword.
return foo()
}
function baz() { // This function is obviously async because it contains an await keyword.
console.log(await bar())
}
baz()
此外,await 关键字也不需要,因为它会产生微妙的问题:
async function foo() {
throw new Error('foo');
}
async function bar() {
try {
return foo();
} catch (err) {
console.log('caught with bar');
}
}
bar(); // UnhandledPromiseRejectionWarning: Error: foo
它可以被 nowait 关键字代替,如果它是一个承诺,则默认解析每个函数调用:
async function foo() {
throw new Error('foo');
}
async function bar() {
try {
return nowait foo(); // Now we clearly see what can cause the problem.
} catch (err) {
console.log('caught with bar');
}
}
bar(); // UnhandledPromiseRejectionWarning: Error: foo
通过结合这两种方法,我们得到了一个干净的代码:
function foo() { // This function is async by default.
return new Promise(function(resolve)
{
setTimeout(function(){resolve("RESULT")},1000)
})
}
function bar() { // This function is deliberately sync because every function call in it is prepended by a nowait keyword.
return nowait foo()
}
function baz() { // This function is also async because not EVERY function call is prepended by a nowait
console.log(nowait bar()) // Promise { <pending> }
console.log(bar()) // "RESULT"
}
baz()
还可以同时使用sync/async 和await/nowait 关键字来让每个人都开心。
在那个推理中我是否遗漏了一些重要的东西?
【问题讨论】:
-
因为 javascript 的目标始终是保持事物的追溯兼容性。您提议的更改将破坏现有代码
-
console.log(nowait bar()) // Promise { <pending> }为什么会得到这个输出?bar不应该是同步的吗? -
这需要对应用程序中的所有代码(包括依赖项)进行完整的静态分析。为了确定所有可能的返回值类型,至少需要对代码进行最少的伪运行,这在像 JS 这样的动态语言中充其量是有问题的,特别是因为对象本身可以在运行时修改。这是一个寻找问题的解决方案,解决异步函数的低百分比。
-
不相关,但语法高亮似乎不满意
function foo()然后在行上添加注释,然后在下一行打开大括号。不知道为什么。看起来像一个错误。 -
@user619271 不,
async最明确地用于将函数描述为异步。不是相反。
标签: javascript asynchronous async-await