Javascript 为什么JS中存在async关键字?

Javascript 为什么JS中存在async关键字?,javascript,asynchronous,async-await,Javascript,Asynchronous,Async Await,如果可以通过函数代码中的wait关键字自动确定,为什么每次都要在每个异步函数之前写入async关键字 函数foo{//此函数是同步的,因为它没有wait关键字。 返回新的承诺 { setTimeoutfunction{resolveRESULT},1000 } } 函数栏{//此函数是同步的,因为它没有等待关键字。 返回foo } 函数baz{//此函数显然是异步的,因为它包含一个wait关键字。 控制台。等待栏 } 巴兹 此外,也不需要使用wait关键字,因为它会产生一些微妙的问题: asyn

如果可以通过函数代码中的wait关键字自动确定,为什么每次都要在每个异步函数之前写入async关键字

函数foo{//此函数是同步的,因为它没有wait关键字。 返回新的承诺 { setTimeoutfunction{resolveRESULT},1000 } } 函数栏{//此函数是同步的,因为它没有等待关键字。 返回foo } 函数baz{//此函数显然是异步的,因为它包含一个wait关键字。 控制台。等待栏 } 巴兹 此外,也不需要使用wait关键字,因为它会产生一些微妙的问题:

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关键字让每个人都感到高兴。
我在这个推理中遗漏了什么重要的东西吗?

我将从开发人员的角度来回答这个问题,而不是从技术角度

你显然错过了一件事,那就是历史

首先,当JS第一次被开发时,网络是非常非常不同的。因此,您可能不喜欢某些解决方案,但这些决定是很久以前做出的

如果不破坏90%的web,就无法从非阻塞切换到阻塞行为。你能想象这样的决定会引起开发者的愤怒吗?此外,JS在用户浏览器上运行,我们无法控制用户更新浏览器。在发送JS脚本之前检查用户的浏览器版本不是一个选项

现在,使用wait的每个函数都需要返回一个承诺,否则它就没有任何意义


这就是引入async关键字的原因——您查看函数,第一眼就知道它返回一个承诺,因为每个异步函数都返回一个承诺。否则,您必须分析整个函数的代码,并检查它是否包含任何等待操作。

因为javascript总是以保持可追溯性为目标。像您建议的更改将破坏现有的codeconsole.lognowait条//承诺{}为什么会得到此输出?bar不应该是同步的吗?这需要对应用程序中的所有代码(包括依赖项)进行完整的静态分析。为了确定所有可能的返回值类型,它至少需要对代码进行一次最小的伪运行,而在JS这样的动态语言中,这些返回值类型充其量是有问题的,特别是因为对象本身可以在运行时修改。这是一个寻找问题的解决方案,解决了异步函数所占比例低的问题。不相关,但语法highlighter似乎不喜欢函数foo,然后在行上添加注释,然后在下一行添加开头的花括号。不知道为什么。看起来像是个bug。@user619271不,async最确切地用来描述异步函数。不是相反。据我所知,异步函数不仅可以返回承诺,这就是我在示例中引入bar函数的原因。现在我测试了它,可以看出我错了!这是许多开发人员忘记的。异步函数fn{return abc;}返回一个承诺,并用值abc自动解析。