0

In the below pseudocode, when the for loop executes each iteration, then will the for loop block at each iteration waiting for the response of the async fetch (because await is used within the myasyncfn? Or do I need to use await keyword as shown in the comment below?

async myasyncfn(url){
return await fetch(url..).response;
}

for each url in url_array:
   myasyncfn(url);    #await myasyncfn(url)
variable
  • 8,262
  • 9
  • 95
  • 215

1 Answers1

1

It will not wait for the async function to complete before continuing the loop; in that sense, it will block. However, that just means it iterates through all URLs in quick succession, firing many fetch requests, which will then all run in the background in parallel. Once the loop is done firing those, your thread is unblocked.

To illustrate:

async function foo(i) {
    await new Promise(resolve => setTimeout(resolve, 5000));
    console.log('Completed', i);
}

for (let i = 0; i < 10; i++) {
    foo(i);
    console.log('Fired', i);
}

console.log('Done firing all async functions, unblocking...');
deceze
  • 510,633
  • 85
  • 743
  • 889
  • Say at iteration 1, when the myasyncfn is invoked, then there is await within the myasyncfn - is that not sufficient for it to block the fetch operation and therefore the for loop? – variable Feb 17 '22 at 08:43
  • It'll "block" the completion of `myasyncfn`, but it'll be suspended in the background until `fetch` has completed and not block the main tread. – deceze Feb 17 '22 at 08:44
  • Your answer is correct, but technically, at the 1st iteration when the main thread invokes foo, then within the function why doesn't the main thread block the iteration at the await within foo? What's this concept called so I can read about it? – variable Feb 17 '22 at 18:09
  • `await` explicitly removes the function from the main thread. It suspends the function’s execution, *because that function needs to wait for something else and can’t continue right now*, and allows other things to happen on the main thread. Keyword to search for: *generators*. Read `await` as “this function now needs to await some result and can thus be removed from (blocking) execution for the time being.” – deceze Feb 17 '22 at 19:32
  • (In Javascript `await` is usually just syntactic sugar for callback functions and thus generator-suspension usually doesn’t really apply, but conceptually it does and other languages implement it that way.) – deceze Feb 17 '22 at 19:34
  • In place of `await new Promise(resolve => setTimeout(resolve, 5000));` suppose I had `new Promise(resolve => setTimeout(resolve, 5000)).then(console.log('Completed', i));` and the next line removed off, then would the meaning remain the same please? And that in both the cases each iteration of the for loop will call the setTimeout, put it into the web api along with the callback and proceed ahead with the loop (and then once each timeout is exhausted, the web api will put the callback into the macro queue)? – variable Feb 18 '22 at 12:10
  • `.then(console.log('Completed', i))` would *not* do what you think it does, it needs to be `.then(() => console.log('Completed', i))`. — But yes, `await` is basically syntactic sugar for *this*. – deceze Feb 18 '22 at 12:25
  • Ah got it. Thank you. Until yesterday I thought that when the code comes to the Promise line, it maybe put it into some web api but now its great to realize that Promise is executed at each iteration and the call back is what gets added to the queue. I also attempted to answer this with my newly gained knowledge: https://stackoverflow.com/a/71173034/1779091- I hope it helps everyone. – variable Feb 18 '22 at 12:29