In JavaScript, does using await inside a loop block the loop?

前端 未结 8 2421
南旧
南旧 2020-12-02 06:38

Take the following loop:

for(var i=0; i<100; ++i){
    let result = await some_slow_async_function();
    do_something_with_result();
}
相关标签:
8条回答
  • 2020-12-02 07:16

    ad 1. Yes. No.

    ad 2. Yes. No.

    Proof:

    async function start() 
    {
      console.log('Start');
    
      for (var i = 0; i < 10; ++i) {
        let result = await some_slow_async_function(i);
        do_something_with_result(i);
      }
      
      console.log('Finish');
    }
    
    function some_slow_async_function(n) {
      return new Promise(res => setTimeout(()=>{
        console.log(`Job done: ${(2000/(1+n))|0} ms`);
        res(true);
      },2000/(1+n)));
    }
    
    function do_something_with_result(n) {
      console.log(`Something ${n}`);
    }
    
    start();

    0 讨论(0)
  • 2020-12-02 07:16

    Does await block the loop? Or does the i continue to be incremented while awaiting?

    No, await won't block the looping. Yes, i continues to be incremented while looping.

    Is the order of do_something_with_result() guaranteed sequential with regard to i? Or does it depend on how fast the awaited function is for each i?

    Order of do_something_with_result() is guaranteed sequentially but not with regards to i. It depends on how fast the awaited function runs.

    All calls to some_slow_async_function() are batched, i.e., if do_something_with_result() was a console then we will see it printed the number of times the loop runs. And then sequentially, after this, all the await calls will be executed.

    To better understand you can run below code snippet:

    async function someFunction(){
    for (let i=0;i<5;i++){
     await callAPI();
     console.log('After', i, 'th API call');
    }
    console.log("All API got executed");
    }
    
    function callAPI(){
    setTimeout(()=>{
    console.log("I was called at: "+new Date().getTime())}, 1000);
    }
    
    someFunction();

    One can clearly see how line console.log('After', i, 'th API call'); gets printed first for entire stretch of the for loop and then at the end when all code is executed we get results from callAPI().

    So if lines after await were dependent on result obtained from await calls then they will not work as expected.

    To conclude, await in for-loop does not ensure successful operation on result obtained from await calls which might take some time to finish.

    In node, if one uses neo-async library with waterfall, one can achieve this.

    0 讨论(0)
提交回复
热议问题