最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - why is async-await much slower than promises when running them together - Stack Overflow

programmeradmin2浏览0评论

I found out that running async-await can be much slower in some scenarios.

<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>

I found out that running async-await can be much slower in some scenarios.

<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, the console.log in usingPromises should print similar results to the one in usingAwait. But in reality, I get:

Total (promises): 0.25 ms

Total (await): 2.065 ms

Also, after the page load, if I click on 'usingPromises' or 'usingAwait' button I get similar results for each of them. (both are fast when running alone)

Total (promises): 0.060000000026775524 ms

Total (await): 0.08999999999650754 ms

But if I click on the 'both' button, the 'await' version is ~3-4 times slower than the promises version.

I have a real application running lots of promises / async-await function on initialisations, and I found out that replacing some of the async-await functions to their "equal" promises version can shave significant loading time (~200ms).

Can someone explain why is that? Isn't async-await also using the same job queue as promises (micro task)? Are there best practices to when should promises should be used instead of async-await?

  • Running on chrome 62 on mac

Thanks

Share Improve this question asked Nov 11, 2017 at 10:47 avivravivr 2,5933 gold badges24 silver badges36 bronze badges 2
  • 1 Actually, running Chrome on Mac as well, async-await is much faster over here: Total (await): 0.07500000000004547 ms and Total (promises): 0.75 ms. Could be a hardware related thing. Async-Await is using Promises internally. – NikxDa Commented Nov 11, 2017 at 10:54
  • 1 NB: Calling runBoth gives twisted results, because the promise resolutions are sequenced in the event queue: so one gets to print with console.log before the other, and it is that console.log that brings additional delay to the second. It would already be an improvement if you would define runBoth as Promise.resolve().then(usingAwait).then(usingPromises). – trincot Commented Nov 11, 2017 at 11:05
Add a ment  | 

1 Answer 1

Reset to default 6

Your first result, when running with the button Both, is misleading. The promise resolutions are sequenced in the microtask event queue: so one gets to print with console.log before the other, but it is that console.log that brings additional delay to the second, because it happens between the creation of the second promise and the treatment of its resolution.

It would already be an improvement if you would define runBoth as:

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

Now both promises will be created in microtasks, and the first one will be resolved and dealt with before the second promise is created. That will lead to a more fair parison where console.log is not measured in any of the timings.

发布评论

评论列表(0)

  1. 暂无评论