JavaScript Promise和异步等待之间有什么区别?

IT技术 javascript asynchronous promise async-await
2021-02-09 16:30:02

我已经在我的应用程序中使用了ECMAScript 6和 ECMAScript 7 特性(感谢 Babel)——移动和网络。

第一步显然是达到 ECMAScript 6 级别。我学习了许多异步模式、promise(确实很有前途)、生成器(不知道为什么是 * 符号)等等。其中,promise 非常适合我的目的。我一直在我的应用程序中使用它们很多。

这是我如何实现基本Promise的示例/伪代码-

var myPromise = new Promise(
    function (resolve,reject) {
      var x = MyDataStore(myObj);
      resolve(x);
    });

myPromise.then(
  function (x) {
    init(x);
});

随着时间的流逝,我碰到的ECMAScript来到7层的功能,并把它们作为一个ASYNCAWAIT关键字/功能。这些结合起来创造了巨大的奇迹。我已经开始用async & await. 它们似乎为编程风格增添了巨大的value。

同样,这里是我的 async, await 函数的伪代码 -

async function myAsyncFunction (myObj) {
    var x = new MyDataStore(myObj);
    return await x.init();
}
var returnVal = await myAsyncFunction(obj);

把语法错误(如果有的话)放在一边,我觉得它们都做完全相同的事情。我几乎可以用 async,await 代替我的大部分Promise。

当 Promise 做类似的工作时,为什么需要 async,await?

async,await 是否解决了更大的问题?或者它只是回调地狱的不同解决方案?

正如我之前所说,我可以使用 promises 和 async,await 来解决同样的问题。async await 有什么具体解决的吗?

补充笔记:

我一直在我的 React 项目和 Node.js module中广泛使用 async、await 和 promises。React 尤其是早期的鸟儿,并采用了许多 ECMAScript 6 和 ECMAScript 7 特性。

6个回答

当 Promises 做类似的工作时,为什么需要 async,await ?async,await 是否解决了更大的问题?

async/await只是让您对异步代码有一种同步的感觉。这是一种非常优雅的语法糖形式。

对于简单的查询和数据操作,Promises 可以很简单,但是如果您遇到涉及复杂数据操作和其他内容的场景,如果代码看起来好像是同步的(换句话说,语法本身就是一种async/await可以绕过的“偶然复杂性”形式)。

如果您有兴趣知道,您可以使用像co(与生成器一起)之类的库来提供相同的感觉。已经开发了这样的东西来解决async/await最终解决的问题(本机)。

请您详细说明“偶然复杂性”是什么意思?还有,说到性能,两者有没有区别?
2021-03-20 16:30:02
我发现这个解释很有帮助nikgrozev.com/2015/07/14/...
2021-04-01 16:30:02
非常感谢!这是我从你那里得到的一些重要信息。是的,不会研究微优化。
2021-04-05 16:30:02
@bozzmob,shaffner.us/ cs/papers/ tarpit.pdf <-- 他在那里解释了“偶然的复杂性”。至于你的性能问题,我对此表示怀疑,尤其是在 V8 引擎的情况下。我确信那里有一些性能测试,但我不会太担心。不要在没有必要时将时间浪费在微优化上。
2021-04-11 16:30:02

Async/Await 在更复杂的场景中提供了更好的语法。特别是处理循环或某些其他结构(如try/ )的任何内容catch

例如:

while (!value) {
  const intermediate = await operation1();
  value = await operation2(intermediate);
}

这个例子仅仅使用 Promises 会更加复杂。

我认为当没有人在他们的代码示例中使用 try/catch 块时,很多人会感到困惑和/或误导。
2021-03-20 16:30:02
是的,我同意它不是标准的一部分,但是,对于 ReactJS(特别是 React Native),我有点被迫在代码的某些部分使用它。所以,其中一半是 promise,一半是 async-await。所以,我问了你这些问题。感谢您提供需要的信息。
2021-03-23 16:30:02
你的意思是这样? const getValue = value => value || operation1().then(operation2).then(getValue);
2021-03-26 16:30:02
这是理解相同内容的一个很好的例子。那么,说到性能,两者有没有什么区别呢?在代码中使用哪个更好?至少在看到您的示例后,Async Await 似乎更好。
2021-03-29 16:30:02
@bozzmob:性能没有区别。如果您习惯于使用 async/await,那么我会推荐它。我自己还没有使用它,因为它实际上不是官方标准的一部分。
2021-04-05 16:30:02

当 Promises 做类似的工作时,为什么需要 async,await ?async,await 是否解决了更大的问题?还是只是回调地狱的不同解决方案?正如我之前所说,我可以使用 Promises 和 Async,Await 来解决同样的问题。Async Await 解决了什么具体问题吗?

您首先必须了解async/await语法只是用于增强Promise的语法糖。事实上,async函数的返回值是一个promise。async/await语法为我们提供了以同步方式编写异步的可能性。下面是一个例子:

Promise链:

function logFetch(url) {
  return fetch(url)
    .then(response => response.text())
    .then(text => {
      console.log(text);
    }).catch(err => {
      console.error('fetch failed', err);
    });
}

Async 功能:

async function logFetch(url) {
  try {
    const response = await fetch(url);
    console.log(await response.text());
  }
  catch (err) {
    console.log('fetch failed', err);
  }
}

在上面的例子中,await等待Promise(fetch(url))被解决或拒绝。如果 promise 被解析,则值存储在response变量中,如果 promise 被拒绝,它将抛出错误并因此进入catch块。

我们已经可以看到,使用async/await可能比 promise 链接更具可读性。当我们使用的 Promise 数量增加时尤其如此。Promise 链和async/await解决回调地狱的问题以及您选择哪种方法是个人喜好的问题。

利弊的全面比较。

纯 JavaScript

  • 优点
  • 不需要任何额外的库或技术
  • 提供最佳性能
  • 提供与第三方库的最佳兼容性
  • 允许创建临时和更高级的算法
  • 缺点
  • 可能需要额外的代码和相对复杂的算法

异步(库)

  • 优点
  • 简化最常见的控制流模式
  • 仍然是基于回调的解决方案
  • 很棒的表演
  • 缺点
  • 引入外部依赖
  • 对于高级流程来说可能仍然不够

Promise

  • 优点
  • 大大简化了最常见的控制流模式
  • 强大的错误处理
  • ES2015 规范的一部分
  • 保证延迟调用 onFulfilled 和 onRejected
  • 缺点
  • 需要 promisify 基于回调的 API
  • 引入了一个小的性能影响

发电机

  • 优点
  • 使非阻塞 API 看起来像阻塞 API
  • 简化错误处理
  • ES2015 规范的一部分
  • 缺点
  • 需要一个互补的控制流库
  • 仍然需要回调或Promise来实现非顺序流
  • 需要 thunkify 或 promisify 非基于生成器的 API

异步等待

  • 优点
  • 使非阻塞 API 看起来像阻塞
  • 简洁直观的语法
  • 缺点
  • 需要 Babel 或其他转译器和一些配置才能在今天使用
这是从哪里复制的?至少其中一些位于Node.js 设计模式(第二版)一书中的第 136-137 页(ISBN-10:1785885588)
2021-03-27 16:30:02

在需要复杂控制流的情况下,Async/await 可以帮助使您的代码更清晰、更具可读性。它还生成更易于调试的代码。并且可以仅使用try/catch.

我最近写了这篇文章,展示了在一些常见用例中 async/await 优于 promises 的代码示例:JavaScript Async/Await Blows Promises Away 的 6 个原因(教程)