javascript - 为什么 async-await 一起运行时比 promises 慢得多

标签 javascript asynchronous async-await es6-promise

我发现在某些情况下运行 async-await 会慢很多。

<html>
  <script>
    function makeAPromise() {
      return Promise.resolve(Math.random());
    }

    function usingPromises() {
      const before = window.performance.now();
      return makeAPromise().then((num) => {
        const after = window.performance.now();
        console.log('Total (promises): ', after-before, 'ms');
        return num;
      })
    }

    async function usingAwait() {
      const before = window.performance.now();
      const num = await makeAPromise();
      const after = window.performance.now();
      console.log('Total (await): ', after-before, 'ms');
      return num;
    }

    function runBoth() {
      usingAwait();
      usingPromises();
    }
    
    runBoth();

  </script>

  <button onclick="usingPromises()">usingPromises</button>
  <button onclick="usingAwait()">usingAwait</button>
  <button onclick="runBoth()">both</button>
</html>

IMO,usingPromises 中的 console.log 应该打印与 usingAwait 中类似的结果。 但实际上,我得到:

Total (promises): 0.25 ms

Total (await): 2.065 ms

另外,在页面加载后,如果我点击“usingPromises”或“usingAwait”按钮,我会得到类似的结果。 (单独跑的时候都快)

Total (promises): 0.060000000026775524 ms

Total (await): 0.08999999999650754 ms

但是如果我点击“both”按钮,“await”版本比 promises 版本慢 ~3-4 倍。

我有一个真实的应用程序在初始化时运行大量的 promises/async-await 函数,我发现将一些 async-await 函数替换为它们的“相等”promises 版本可以显着缩短加载时间(~200 毫秒)。

有人能解释一下这是为什么吗? async-await 不也是和 promises(微任务)一样使用同一个作业队列吗?是否有关于何时应使用 promises 而不是 async-await 的最佳实践?

  • 在 mac 上运行 chrome 62

谢谢

最佳答案

当您使用按钮 Both 运行时,您的第一个结果具有误导性。 promise 决议在微任务事件队列中排序:因此一个人可以在另一个之前使用 console.log 进行打印,但是 console.log 会导致额外的延迟第二个,因为它发生在第二个 promise 的创建和它的解决方案的处理之间。

如果您将 runBoth 定义为:

Promise.resolve().then(usingAwait).then(usingPromises)

现在两个 promise 都将在微任务中创建,第一个将在创建第二个 promise 之前解决和处理。这将导致更公平的比较,其中 console.log 未在任何时间测量。

关于javascript - 为什么 async-await 一起运行时比 promises 慢得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47237054/

相关文章:

javascript - 如何在隔离范围内创建嵌套对象

javascript - 切换 navigator.online

javascript - 如何/可以连接/组合数组中的单个字符串吗?

c# - 转换使用任务的便捷方法

c# - 并行循环调用中的进度条

javascript - 右键单击 JavaScript 不适用于 PHP 中的表格

c++ - handler失败后怎么办?

asynchronous - 无法使用 `impl Future` 将异步函数存储在向量中

node.js - 是否有替代已弃用的 deferred.callback 的替代品?

javascript - Node 在继续之前等待异步功能