async function foo() {
try {
const response = await fetch("https://www.xxx.xxx");
const data = await response.json();
console.log(data);
} catch (e) {
console.log("Error!!: ", e);
}
}
foo();
console.log('111');
Assuming that there is a code like this, the execution result is
111 -> Error: TypeError: Failed to fetch
And that’s what happens when I think about the execution context process, depending on the code flow
-
When the foo function is called, the execution context of the foo function is created and added to the call stack.
-
When fetch ("https://www.xxx.xxx ") runs within the try block, the execution context of the fetch function is created and added to the call stack. This is when a network request is made in the background. The fetch function returns a Promise and the execution context of the fetch function is removed from the call stack.
-
subsequent actions after the await keyword are added to the micro-task queue.
-
The foo function ends, removing the execution context of the foo function from the call stack.
-
console.log (‘111) is executed and "111" is output to the console.
-
Since the call stack is empty, subsequent operations after await that were queued in the micro-task queue are sequentially moved to the call stack and executed.
-
The fetch function’s network request fails and a reject is called, causing Promise’s status to be rejected.
-
How do you catch an error???
The try/catch statement is a little confusing.
In order for console.log (‘111) to run, the call stack must be empty, but how does the catch in the foo function that has already ended get an error??
please help me!
3
Answers
maybe this points can help you :
console.log(111)
is called beforefoo()
promise completion.foo()
, you need to add.catch(err => ...)
Note, you can add
await
before the call to foo in order to have sequential calls after, thus console.log(111) will be called after promise completionSince your
foo()
is async, everything afterawait
is executed async, so afterconsole.log('111')
which is sync. So useawait foo()
to wait forfoo()
to be settled (resolved or rejected) beforeconsole.log('111')
. If you want to catch an error fromfoo()
you should rethrow your error.Regarding your question what happens with the call stack I wouldn’t bother, but I would imagine
async/await
as substitution of.then().catch()
so basically afterawait
and in acatch
block you have completely different functions placed in a call stack in the moment of their executions. The only problem that afterawait
for example you have assess to variables defined beforeawait
. Consider it as magic of attaching one scope to another…Some scope magic:
You have it the wrong way around. The call stack has to be empty in order to continue from
await fetch()