0

I state that I am not an expert in JavaScript, and I am now starting to deepen it.

This post aims to clarify some doubts about the async / away functions that I'm just starting to deepen.

The example below leaves me perplexed on the sequence of execution that seems, from the logs printed on the console, different from what I expected.

Before exposing my doubt and my question for clarification I show you my example code:

async function fetchAlbum(id){
    let album;
    album = await fetch(albumUrl + '/' +id)
    .then( resp => resp.json())
    .then(albumcontent => albumcontent);

    console.log('Concrete Value 1',album); //Here is printed the concrete value thanks to await is not undefined
    
    return album; //Here the concrete value is wrapped by a promise (the value is returned to the caller in the form of a promise)
}

let alb = fetchAlbum(1);
console.log('Promise 1',alb); //Print a promise... will be the first logged (!?)
alb.then(alb => console.log('Concrete Value 2',alb)); //We have the album again as a concrete value (the album object)

I created an async function fetchAlbum within which I resolve the promises returned by the fetch () API by prefixing await. Therefore, I expect that at the call fetchAlbum (1) the code waits until the "return album" is performed inside the function async fetchAlbum (id). But in reality, this is not the case. Looking at the tracks on the console, I see:

"Promise 1", then "Concrete Value 1" and finally "Concrete Value 2", the latter printed by the callback function of the promise returned by the async fetchAlbum function.

What I understand is that JavaScript (ES6), just called an async function, returns the promise continuing with the flow of execution following the call let alb = fetchAlbum (1); and as soon as the chain of promises is finished, it will print "Concrete Value 1" and finally, it will pass for "return album".

The question is, assuming my guess is correct, how does JavaScript immediately return the promise (in pending state) without going through the "return"?

I am still a bit confused and any suggestion to understand will be very welcome for me.

I hope I have exposed my perplexity and my question in the most understandable way possible.

Thanks a lot.

  • *"I expect that at the call fetchAlbum (1) the code waits"*: no, JavaScript just suspends that function, returning from it, and continues with whatever is coded after the function call, until its callstack is empty. – trincot Nov 03 '21 at 19:59
  • @trincot, Thank you, So the statement return of the async function will be performed when the stack of instructions following the function call is exhausted? What is not clear to me is how JavaScript manages to return the reference to the promise in a pending state before continuing. Thanks again! – user1175801 Nov 03 '21 at 20:09
  • 1
    Yes, the engine always creates a pending promise when executing an `async` function. This is by design. When the `await` is encountered, and the expression following it is evaluated (often a pending promise), then the function's execution state is saved, and the function returns the new pending promise. When the (other) promise related to the `await` resolves, then the function's execution context is restored, the `await` expression will evaluate to the resolved value, and execution continues in that function. When it `return`s, the `async` promise resolves. – trincot Nov 03 '21 at 20:39
  • 1
    See also [In JavaScript, does using await inside a loop block the loop?](https://stackoverflow.com/q/44410119/5459839) – trincot Nov 03 '21 at 20:39
  • @trincot Thank you for your excellent deepening and your explanation. So, I can affirm is that an async function, such as async f (), is transformed into something like this: declared async is transformed into: const f = Promise ((resolve, reject) => { // Body async f () }) Is it plausible as an interpretation? Thanks again! – user1175801 Nov 03 '21 at 20:50
  • 1
    It is a possible interpretation, but that only covers the fact that an `async` function returns a promise. There is no `resolve` or `reject` callback. Instead the promise resolves when it executes a `return` (or implicitly does so after having executed its last statement), and it rejects when an error is thrown. And, most importantly, it supports the `await` keyword, which can only occur together with `async`. `await` has some correspondence with `yield`, which also saves the function's execution state for resuming it later. – trincot Nov 03 '21 at 20:56
  • Thanks, you were really clear! – user1175801 Nov 03 '21 at 21:07

0 Answers0