首页 文章

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

提问于
浏览
66

我已经在我的应用程序中使用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 替换我的一些承诺 . 它们似乎为编程风格增添了很多 Value .

同样,这里是我的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模块中广泛使用async,awaits和promise . React特别是早期的鸟类,并采用了很多ECMAScript 6和ECMAScript 7功能 .

6 回答

  • 26

    为什么异步,等待Promises做类似的工作? async,等待解决更大的问题吗?

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

    对于简单的查询和数据操作,Promises可以很简单,但是如果你遇到的情况更容易理解,如果代码看起来好像它是同步的话会发生什么(换句话说,语法本身就是一种形式的"incidental complexity", async/await 可以绕过) .

    如果您有兴趣知道,可以使用像co这样的库(和发电机一起)来提供同样的感觉 . 这样的事情已经被开发出来以解决 async/await 最终解决的问题(原生) .

  • 53

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

    例如:

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

    只使用Promises,这个例子会更复杂 .

  • 6

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

    我最近写了这篇文章,展示了async / await over promises在一些常见用例中的优点,代码示例为https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9

  • 6

    充分比较利弊 .

    Plain JavaScript

    • 优点

    不需要任何其他库或技术可提供最佳性能提供与第三方库的最佳兼容性允许创建临时和更高级的算法

    • 缺点

    可能需要额外的代码和相对复杂的算法

    Async (library)

    • 优点

    Simpli fi es最常见的控制流模式仍然是基于回调的解决方案良好的性能

    • 缺点

    引入外部依赖可能还不足以应对高级流程

    Promises

    • 优点

    大大简化最常见的控制流模式鲁棒的错误处理ES2015规范的一部分保证onFulfilled和onRejected的延迟调用

    • 缺点

    需要promisify基于回调的API引入小的性能影响

    Generators

    • 优点

    使非阻塞API看起来像一个阻塞的Simpli fi es错误处理部分ES2015规范

    • 缺点

    需要一个补充控制流库仍需要回调或承诺来实现非顺序流程需要thunkify或promisify基于非生成器的API

    Async await

    • 优点

    使非阻塞API看起来像阻塞清晰直观的语法

    • 缺点

    今天需要使用Babel或其他转发器和一些配置

  • 1

    我的问题是,为什么当Promises做类似的工作时,async需要等待吗? async,等待解决更大的问题吗?或者它只是回调地狱的另一种解决方案?正如我之前所说,我能够使用Promises和Async,Await来解决同样的问题 . 是否存在Async Await解决的具体内容?

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

    Promise chaining:

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

    Async function:

    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链接和 async / await 都解决了回调地狱的问题,你选择哪种方法是个人喜好的问题 .

  • 3

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

    Promise

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

    在执行下一步之前,调用代码可以等到该promise完成 . 为此,promise具有名为 then 的方法,该方法接受将在履行承诺时调用的函数 .

    Async/await

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

    异步函数可以包含一个await表达式,它暂停执行异步函数并等待传递的Promise的解析,然后恢复异步函数的执行并返回已解析的值

    异步/等待超过承诺的优点

    构造

    • Async / await是为了给异步操作的延续语义提供一个干净的语法 .

    • 它避免了回调/承诺地狱 .

相关问题