为什么可以赋值`async`和`await`关键字? [复制]

2023-12-10

我注意到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(使用前将#替换为@)

为什么可以赋值`async`和`await`关键字? [复制] 的相关文章

随机推荐