javascript - 为什么 `async`和 `await`关键字可以赋值?

标签 javascript ecmascript-6

<分区>

我注意到 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));

甚至 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 language specifications .所以 async 只有在后面跟着 function 时才具有特殊含义——作为表达式(传统函数和箭头函数)或作为声明。因此,名为 async变量 是有效的,因为后跟 function 的变量在语法上是无效的。与语义没有冲突:

let foo;

//function declaration
foo function bar() {}; //SyntaxError

let foo;

//function expression
let bar = foo function() {}; //SyntaxError

  • 至于await,它实际上是一个运算符,而不是关键字,它是await expression (MDN) 的一部分。 : link to the specs .语义要求 await 后跟一元表达式 and 以位于 async 函数内 - 这在语法上仍然不适用于其他变量。

我没有这方面的任何来源,但可以合理地得出结论,这样做是为了保持向后兼容性。如果有代码在 ES5 中使用 async 作为变量,稍后它会突然中断。通过使 async 仅在出现 SyntaxError 的情况下有效,确保旧代码和新代码可以共存。 await 也是如此。

有趣的是,await 的语义实际上导致了最初又很奇怪的行为 - 您不能将它用作 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 函数中使用它,因为那些不存在。因此,旧代码有效并且仍然没有冲突。

关于javascript - 为什么 `async`和 `await`关键字可以赋值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56869954/

相关文章:

javascript - 当 div 的内容发生变化时,如何自动将 div 的大小调整为其内容的大小?

javascript - 提交没有提交按钮的复选框状态

javascript - 使用正交相机将鼠标点击转换为 3D 空间

javascript - React Native - 从子级调用父级引用函数

javascript - 计算对象属性的重复数组以生成新数组

javascript - 当在 Chrome 的多功能框中按下输入键时,Keyup 事件监听器会触发

javascript - jquery 1.10.2 与 Firefox 29.0.1 冲突

JavaScript : How to write Square bracket in array element

javascript - 在 ES6 中创建多个构造函数

javascript - es6中使用map过滤并返回一个新对象