To a traditional programmer, async / await can be tricky. Here are some key concepts:
- There cannot be any
await
inside of a function if this function is not declared as an async function. - You can think of it this way: this async function returns to you immediately, and what does it return? It returns a promise that will be resolved or rejected later.
- Inside of the async function, the code will run, until it hits an
await
. Don't think of thisawait
as "waiting", but more like anotifyMeOfTheValueWhenReady
oraValueThatWillBeReady
. You can even read it asstopHereAndGiveMeTheValueWhenReady
. - To be more precise, the promise isn't returned to the caller until the first
await
is reached. Typically you will have at least oneawait
inside an async function, or else you wouldn't use an async function in the first place. You can see in the examples below to verify the case: inside the async function, the code runs until the firstawait
, then the promise is returned to the caller. This usually does not matter, but it may be good to know. - This
await
is like a "set it and forget it". It is similar to setting an observer, if you are familiar with the observer pattern. Or you can think of it as setting a callback function. Theawait
is followed by a promise, likeawait p;
You can think of it as a.then(v => { ... })
, so the valuev
is whatawait p
will become in the future. - When the execution of code reaches this
await
, after the "set it and forget it", nothing is done. The code does not go onto the next line until this "future value", or promise is resolved or rejected. - We can use
price = await getStockPrice();
ordisplayStockPrice(await getStockPrice());
. In the first case, thatawait
reads likenotifyMeOfTheValueWhenReady
. In the second case, theawait
reads likeaValueThatWillBeReady
. For both cases, reading it asstopHereAndGiveMeTheValueWhenReady
goes well. In the second case, theawait
cause the async function code to stop there, until a value is obtained, and thendisplayStockPrice()
is called.
Example 1
In the following, try and figure out the order of the lines are displayed.
Note that $(document).ready(function() { ... });
is just jQuery's way of running the code when the DOM is ready in the jsfiddle environment.
https://jsfiddle.net/kwtomj59/
console.log("Running the program");
async function foo() {
console.log("I am running at Point A of the async function");
return 123;
}
foo().then((v) => {
console.log("finally I get the value from the async function", v);
});
console.log("This is after calling the async function");
Example 2
What about the following? Note that when the big loop is running, the UI of that input box is not reacting.
https://jsfiddle.net/odr4sz58/
console.log("Running the program");
async function foo() {
let a = 0;
for (let i = 0; i < 1000000000; i++) {
a += Math.random() > 0.5 ? 1 : -1;
}
console.log("I am running at Point A of the async function");
return a;
}
foo().then((v) => {
console.log("finally I get the value from the async function, and it is ", v);
});
console.log("This is after calling the async function");
Example 3
Since the console.log
is not executed until later, we can use alert
to see the immediate message:
https://jsfiddle.net/odr4sz58/1/
It is just the above program with the console.log
replaced with alert
.
Example 4
https://jsfiddle.net/hpj4tvy3/
alert("Running the program");
async function foo() {
let a = 0;
const foo = await (new Promise(resolve => setTimeout(() => resolve(123), 0)));
for (let i = 0; i < 1000000000; i++) {
a += Math.random() > 0.5 ? 1 : -1;
}
alert("I am running at Point A of the async function");
return [a, foo];
}
foo().then((v) => {
alert(`finally I get the value from the async function, and it is ${JSON.stringify(v)}`);
});
alert("This is after calling the async function");
Example 5
Finally, here is an example of the fn(await ...)
pattern. What is the order of the messages being displayed?
https://jsfiddle.net/yb0th3cw/
alert("Running the program");
async function foo() {
let a = 0;
alert(await (new Promise(resolve => setTimeout(() => resolve(123), 0))));
for (let i = 0; i < 1000000000; i++) {
a += Math.random() > 0.5 ? 1 : -1;
}
alert("I am running at Point A of the async function");
return a;
}
foo().then((v) => {
alert(`finally I get the value from the async function, and it is ${JSON.stringify(v)}`);
});
alert("This is after calling the async function");
Top comments (0)