我注意到async
关键字可以被赋予任何值,甚至可以用作普通变量:
let async = "world";
console.log(async)
console.log("Hello " + async)
然而,即便如此,它仍然像以前一样运行:
let async = "world";
async function foo(input) {
return input;
}
let barPromise = foo("bar");
console.log("bar promise is:", typeof barPromise);
console.log("bar promise also has a .then:", typeof barPromise.then === "function");
barPromise
.then(output => console.log("bar promise returns:", output));
console.log("async is still assigned:", async);
foo("Hello ")
.then(output => console.log(output + async));
Even await
正在做同样的事情:
let await = "world";
console.log("await is:", await)
async function foo(input) {
return input;
}
async function bar(input) {
console.log("before");
let output = await foo(input);
console.log(output);
console.log("after");
}
bar("hello")
这里发生了什么?为什么关键字可以用作变量?
首先,我们需要澄清一些事情,以使答案的其余部分更有意义:
- 没有
async
关键词。有一个async function
构造:MDN, ECMAScript 语言规范. So async
仅当后跟函数时才具有特殊含义 - 作为表达式(传统函数和箭头函数)或作为声明。因此,一个variable called async
是有效的,因为变量后跟function
在语法上无效。与语义没有冲突:
let foo;
//function declaration
foo function bar() {}; //SyntaxError
let foo;
//function expression
let bar = foo function() {}; //SyntaxError
- as for
await
,这实际上是一个运算符,而不是关键字,它是await表达(MDN): 链接到规格。语义要求await
后跟一元表达式and在一个async
函数 - 与其他变量在语法上仍然无效的东西。
我没有任何来源,但可以合理地得出这样的结论:这样做是为了保持向后兼容性。如果有代码使用async
作为ES5中的一个变量,它稍后会突然崩溃。通过制作async
仅在您收到 SyntaxError 的情况下有效,这确保旧代码和新代码可以共存。同样适用于await
.
有趣的是,语义await
实际上导致了最初又很奇怪的行为——你cannot将其用作内部变量async
功能。要么声明它:
async function foo() {
let await = "world"; //SyntaxError - not a valid identifier here
}
也不访问它:
let await = "world"; //valid identifier
async function foo() {
console.log(await); //SyntaxError - it is not followed by an expression
}
这最初也令人困惑,但是,它对于向后兼容性是有意义的。即使使用 ES6 之前的代码await
作为一个变量,它不会在async
功能因为那些不存在。所以,旧代码works并且仍然没有发生冲突。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)