Reputation: 37
I thought I understood how to use async and await till I saw the below code snippet.
So there is an onInput event handler function attached to the movie input textbox. Within it is called the fetchData asynchronous function which uses the await keyword to wait for results from the axios.get function.
My question is, why do we need to make the onInput function also async? I mean, the fetchData function is async. Which means, it will wait till the axios.get is resolved and the execution will be paused till axios.get is resolved. So when the line const movies = fetchData(event.target.value); executes, the fetchData function will be executed which will pause on the await axios.get statement. So why do we need to use await while calling fetchData and make onInput async??
const fetchData = async(searchTerm)=>{
const results = await axios.get('http://www.omdbapi.com/', {
params:{
apikey:'d9835cc5',
s: searchTerm
}
});
return results.data.Search;
}
const movieInput = document.querySelector('input');
const onInput = async event => {
const movies = await fetchData(event.target.value);
console.log(movies);
}
movieInput.addEventListener('input', onInput);
Upvotes: 2
Views: 2244
Reputation: 19301
I mean, the fetchData function is async. Which means, it will wait till the axios.get is resolved and the execution will be paused till axios.get is resolved.
This concept is hiding a lot of detail that may be confusing, such as that paused execution is resumed using callback functions.
async
functions do not pause execution of their callers.
Instead they return a promise that will be resolved with the value syntactically returned from executing the async
function body. To be clear, the value apparently returned from within an async
function body is not returned to the caller directly - the caller gets a promise for it.
When executed the await
operator sets up call backs for when its operand promise becomes settled. Effectively it calls the then
method of its promise operand to supply a set of onfulfilled
and onrejected
callbacks, before storing the current execution context in memory and returning to the event loop.
When it receives a callback from promise settlement, the await
operator restores the execution context it previously saved. If the awaited promise is rejected, await
throws the rejection reason. If fulfilled, await
resumes exection and returns the fulfilled value of the promise as the result of executing the await
operator.
Now historically await
was never a reserved keyword - not mentioned in ES3, future reserved keyword in ES6 (ECMAScript 2015) but reserved word in the current draft of ECMAscript as at May 2021.
Hence, to retain compatibility with code on the web, await
was only recognized as an operator if it occurs within an async
function - leaving it available as an identifier outside of async
function bodies.
Likewise the async
keyword was not historically reserved, but was able to be introduced without comparability issues by requiring its usage in a position that would have produced an unexpected identifier error in previous versions of JavaScript. Meaning before the function
keyword or before an arrow function expression.
Finally you need to declare onInput
as an async
function because await
is being used as an operator within its body. Without the async
declaraton, await
will be treated as an identifier rather than the name of an operator.
As a side note, the promise returned by onInput
is being discarded and could generate an uncaught promise rejection error in its current form.
To answer the slightly different question of "why does await
need to be used in the onInput
function at all?", the value returned from fetchData
is a pending promise. In order to set movies
to the results.data.Search
value obtained within fetchData
, you need to wait for the fulfilled value of the returned promise. Using async/await
is one means of doing so. The other is to add a fulfillment handler to the promise returned from fetchData
by calling its then
method.
Upvotes: 3
Reputation: 84
In general, you would want API calls to execute while the rest of your program runs, so the onInput
would be async. Furthermore, javascript mandates that an await is inside of an async function, so the code was simply following its standards and rules as well. Typically, once the top level is an async, everything inside of it is just following the structure. More info can be found here.
Upvotes: 0
Reputation: 1021
You are using the await
operator inside inInput
. It's a JavaScript rule that functions using await
must be async, so inInput
must also be async. Have a look at this answer: https://stackoverflow.com/a/56685416/13357440
Also, MDN has useful information: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
Upvotes: 1