为什么可以将`async`和`await`关键字分配给? [英] Why can the `async` and `await` keywords be assigned to?

查看:87
本文介绍了为什么可以将`async`和`await`关键字分配给?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到async关键字可以被分配任何值,甚至可以用作普通变量:

I noticed that the async keyword can be assigned any value whatsoever and even used as a normal variable:

let async = "world";

console.log(async)
console.log("Hello " + async)

尽管如此,它仍然可以像以前一样继续运行:

Yet, even then it continues to operate as before:

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也在做同样的事情:

Even await is doing the same thing:

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")

这是怎么回事?为什么关键字可用作变量?

What is going on here? Why are the keywords usable as a variables?

推荐答案

首先,我们需要对其余答案进行一些澄清,以使其更有意义:

First, we need to clarify some things for the rest of the answer to make more sense:

  • 没有async关键字.有一个async function构造: MDN ECMAScript语言规范.因此,async仅在后接函数时才具有特殊含义-作为表达式(传统函数和箭头函数)或声明.因此,称为async变量是有效的,因为后跟function的变量在语法上无效.与语义没有冲突:
  • there is no async keyword. There is an async function construct: MDN, ECMAScript language specifications. So async only has a special meaning if followed by function - either as an expression (both traditional and an arrow function) or as a declaration. Thus, a variable called async is valid, since a variable followed by function is not syntactically valid. There is no clash with semantics:

let foo;

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

let foo;

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

    await一样,
  • 实际上是运算符,而不是关键字,它是 await表达式(MDN):链接至规范.语义要求await后跟一元表达式,并且必须位于async函数内部-某些语法在语法上仍然无效.
  • as for await, that's actually an operator, not a keyword and it is part of an await expression (MDN): link to the specs. The semantics require await to be followed by a unary expression and to be inside an async function - something that's still not syntactically valid with other variables.

我没有任何消息来源,但是有理由得出这样的结论是为了保持向后兼容性而得出的结论是合理的.如果在ES5中有代码将async用作变量,则稍后会突然中断.通过使async仅在否则会出现SyntaxError的地方有效,可以确保旧代码和新代码可以共存.与await相同.

I don't have any source for this but it's reasonable to conclude that this has been done to preserve backwards compatibility. If there was code that used async as a variable in ES5, it would suddenly break later. By making async only valid where otherwise you get a SyntaxError, that ensures that old code and new code can coexist. Same for await.

有趣的是,await的语义实际上导致了最初又很奇怪的行为-您不能将其用作async函数中的变量.要么声明它:

Interestingly, the semantics of await actually lead to behaviour that is again initially strange - you cannot use it as a variable inside an async function. Either declaring it:

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函数中使用它,因为不存在这些功能.因此,旧代码有效,并且仍然没有冲突.

This is initially confusing as well, however, it makes sense for backwards compatibility. Even if pre ES6 code used await as a variable, it wouldn't have used it in async functions as those didn't exist. So, old code works and there are still not clashes.

这篇关于为什么可以将`async`和`await`关键字分配给?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆