ChatGPT解决这个技术问题 Extra ChatGPT

JavaScript 承诺和异步等待有什么区别?

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

第一步显然是 ECMAScript 6 级别。我学习了许多异步模式、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 替换我的一些承诺。它们似乎为编程风格增加了巨大的价值。

同样,这是我的异步等待函数的伪代码 -

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

撇开语法错误(如果有的话)不谈,我觉得它们都做同样的事情。我几乎已经能够用 async,waits 代替我的大部分承诺。

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

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

正如我之前所说,我可以使用 Promise 和 async,await 来解决同样的问题。有什么特定的异步等待解决了吗?

补充说明:

我一直在我的 React 项目和 Node.js 模块中广泛使用异步、等待和承诺。 React 尤其是早起的鸟儿,采用了许多 ECMAScript 6 和 ECMAScript 7 特性。

您的第一个代码块似乎使用了同步操作的承诺。为什么要这么做?从本质上讲,同步更容易编写代码,因此几乎没有理由将同步操作包装到 Promise 中并强制它现在是异步的。
@jfriend00 是的,你是对的。编辑了代码。谢谢。
您仍在尝试使用具有同步功能的异步工具 - 现在在两个代码块中。为什么?
@jfriend00 好的。这里有我的代码 gist.github.com/bozzmob/26d38b83dc37d1be37f5 。请你能告诉我我做错了什么吗?
听起来您只需要阅读大量内容即可了解 async 和 await 的用途。以下是一些文章:The long road to Async/Await in JavaScriptSimplifying Asynchronous Coding with ES7 Async FunctionsTaming the asynchronous beast with ES7

J
Josh Beam

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

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

对于简单的查询和数据操作,Promise 可以很简单,但如果您遇到复杂数据操作和其他不涉及的场景,如果代码只是 看起来 就好像它是同步的,就更容易理解发生了什么(换句话说,语法本身就是一种 async/await 可以解决的“偶然复杂性”形式)。

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


请您详细说明“偶然的复杂性”是什么意思?另外,在性能方面,两者之间没有区别吗?
@bozzmob,shaffner.us/cs/papers/tarpit.pdf < - 他在那里解释了“偶然的复杂性”。至于您的性能问题,我对此表示怀疑,尤其是在 V8 发动机是这样的情况下。我确信那里有一些性能测试,但我不会担心太多。不要在不必要的时候把时间浪费在微优化上。
非常感谢!这是我从你那里得到的一些重要信息。是的,不会考虑微优化。
我发现这个解释很有帮助nikgrozev.com/2015/07/14/…
S
Stephen Cleary

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

例如:

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

仅使用 Promises,此示例将更加复杂。


这是一个很好的例子来理解这一点。那么,在性能方面,两者没有区别吗?在代码中使用哪个更好?至少看到您的示例后,Async Await 似乎更好。
@bozzmob:性能没有区别。如果您习惯使用 async/await,那么我会推荐它。我自己还没有使用它,因为它实际上并不是官方标准的一部分。
是的,我同意它不是标准的一部分,但是,对于 ReactJS(特别是反应原生),我有点被迫在代码的某些部分使用它。因此,其中一半是承诺,一半是异步等待。所以,我问了你这些问题。感谢您提供需要的信息。
我认为当没有人在他们的代码示例中使用 try/catch 块时,很多人会感到困惑和/或误导。
你是说那样吗? const getValue = value => value || operation1().then(operation2).then(getValue);
P
Peter Mortensen

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

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

承诺链:

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 等待承诺 (fetch(url)) 被解决或拒绝。如果 promise 被解决,则值存储在 response 变量中,如果 promise 被拒绝,则会抛出错误并因此进入 catch 块。

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


P
Peter Mortensen

在您需要复杂的控制流的情况下,异步/等待可以帮助您的代码更清晰、更具可读性。它还生成更易于调试的代码。并且只需 try/catch 即可处理同步和异步错误。

我最近写了这篇文章,通过代码示例展示了在一些常见用例中 async/await 相对于 Promise 的优势:6 Reasons Why JavaScript Async/Await Blows Promises Away (Tutorial)


R
Ran Turner

await/async 通常被称为 promise 的语法糖,让我们等待某些东西(例如 API 调用),给我们一种在实际异步代码中它是同步的错觉,这是一个很大的好处。

你想通过 async/await 实现的事情可以通过 Promise 实现(但没有 async/await 的优势)。让我们以这段代码为例:

const makeRequest = () => //promise way
  getJSON()
    .then(data => {
      return data
    })

makeRequest();

const makeRequest = async () => { //async await way
  const data = await getJSON();
  return data;
 }

makeRequest()

为什么 async/await 比 promise 更受欢迎?

简洁明了 - 我们不必编写 .then 并创建一个匿名函数来处理响应,或者为我们不需要使用的变量提供名称数据。我们还避免了嵌套代码。 async/await 要干净得多。错误处理 - Async/await 最终可以使用相同的 try/catch 格式处理同步和异步错误。调试 - 使用 async/await 的一个非常好的优势是它比 Promise 更容易调试,原因有两个:1) 你不能在返回表达式的箭头函数中设置断点(没有正文)。 2) 如果您在 .then 块中设置断点并使用调试快捷方式(如 step-over),调试器将不会移动到以下 .then ,因为它只会“步进”同步代码。错误堆栈 - 从承诺链返回的错误堆栈让我们不知道错误发生在哪里,并且可能会产生误导。 async/await 为我们提供了从 async/await 指向包含错误的函数的错误堆栈,这是一个非常大的优势。


N
Nikola Pavicevic

Await 语法只是简单的同步代码,因为您必须等到 promise 被履行或被拒绝。实际上 await 关键字之后的代码执行将被暂停,直到 promise 解决或拒绝。


这个“新”答案所做的唯一一件事就是重复一半其他答案已经说过的话,包括接受的答案。