JavaScript promises和async等待有什么区别?

时间:2015-12-21 17:37:54

标签: javascript asynchronous reactjs async-await promise

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

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

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

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,等待解决更大的问题吗?或者它只是回调地狱的另一种解决方案?

正如我之前所说,我能够使用promises和async,等待解决同样的问题。是否存在异步等待解决的具体内容?

附加说明:

我一直在我的React项目和Node.js模块中广泛使用异步,等待和承诺。 React特别是早期的鸟类,并采用了很多ECMAScript 6和ECMAScript 7的功能。

6 个答案:

答案 0 :(得分:56)

  

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

async/await简单地为您提供异步代码的同步感觉。这是一种非常优雅的语法糖形式。

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

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

答案 1 :(得分:27)

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

例如:

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

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

答案 2 :(得分:7)

  

我的问题是,为什么Promises确实需要异步等待   类似的工作?异步等待解决更大的问题吗?还是只是一个   回调地狱的不同解决方案?就像我之前说的,我能够   使用Promises和Async,Await解决相同的问题。在那儿   异步等待解决了什么具体问题?

首先要了解的是async / await语法仅仅是语法糖,旨在增强承诺。实际上,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))被解决或被拒绝。如果承诺已解决,则将值存储在response变量中,如果承诺被拒绝,则会抛出错误,从而进入catch块。

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

答案 3 :(得分:6)

Async / await可以帮助您在需要复杂控制流的情况下使代码更清晰,更易读。它还可以生成更多适合调试的代码。并且只需try/catch即可处理同步和异步错误。

我最近写了这篇文章,展示了在代码示例https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9

的一些常见用例中async / await优于promises的优点

答案 4 :(得分:6)

与利弊完全比较。

普通JavaScript

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

异步(库)

  • 赞成
  
      
  • 简化最常见的控制流程模式
  •   
  • 仍然是基于回调的解决方案
  •   
  • 表现良好
  •   
  • 缺点
  
      
  • 介绍外部依赖
  •   
  • 可能仍然不适合高级流程
  •   

<强>承诺

  • 赞成
  
      
  • 大大简化最常见的控制流程模式
  •   
  • 强大的错误处理
  •   
  • ES2015规范的一部分
  •   
  • 保证延迟调用onFulfilled和onRejected
  •   
  • 缺点
  
      
  • 需要promisify基于回调的API
  •   
  • 推出小型演出
  •   

<强>发电机

  • 赞成
  
      
  • 使非阻塞API看起来像阻塞的
  •   
  • 简化错误处理
  •   
  • ES2015规范的一部分
  •   
  • 缺点
  
      
  • 需要补充控制流程库
  •   
  • 仍需要回调或承诺来实施非连续流动
  •   
  • 需要thunkify或promisify基于非生成器的API
  •   

异步等待

  • 赞成
  
      
  • 使非阻塞API看起来像阻止
  •   
  • 清晰直观的语法
  •   
  • 缺点
  
      
  • 今天需要使用Babel或其他转发器以及一些配置
  •   

答案 5 :(得分:2)

两种都是处理异步代码的方法。但是两者的执行之间存在差异。这是工作执行-

承诺

Promise对象表示异步操作的可能完成(或失败)及其结果值。它是在创建时未必知道的值的代理,它表示异步操作的未来结果。

在执行下一步之前,调用代码可以等待直到实现了诺言。为此,promise具有名为then的方法,该方法接受一个函数,该函数将在实现诺言时被调用。

异步/等待

调用async函数时,它将返回一个Promise。当async函数返回一个值时,将使用返回的值解析Promise。当async函数抛出异常或某个值时,Promise将被抛出的值拒绝。

异步函数可以包含await表达式,该表达式会暂停异步函数的执行并等待所传递的Promise的分辨率,然后恢复异步函数的执行并返回解析的值

  

异步/等待承诺的优点

    构造
  • Async / await是为了给 异步操作的延续语义。
  • 它避免了回调/承诺地狱。