Difference between Async/Await and Promises
Async Await functions works similar to Promises, with minor differences.
When you use a Promise, the single thread asynchronously executes your async operation and then continues and executes the next line of code.
Whereas in Async/Await, it will execute all of the Await first, before moving on.
Example – Async/Await vs Async/Promise
We have a getWebcast function that is going to wait 2 seconds of wait time and then returns data. This simulates a fetch operation that goes to a server, retrieves some data and returns it.
1 2 3 4 5 6 7 8 9 10 |
function getWebcast () { console.log('-- getWebcast --'); // async function requires a Promise object to be returned return new Promise( (resolve, reject) => { setTimeout( () => { resolve({data: 'payload'}) }, 2000); }); } |
The execution of a Promise is always asynchronous.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function F() { console.log(`-- F --`); let result = getWebcast(); console.log('-- result of fetch in F --'); console.log(result); console.log(`using Promises -- end of F --`); } F(); console.log('end of script...'); |
The result is:
— F —
— getWebcast —
PromiseĀ {
— result of fetch in F —
using Promises — end of F —
end of script…
You see that the function execute. The returned Promise returned by F() is a pending Promise and no one is using it. It executes line by line down the list.
In order to solve this asynchronous issue, we use .then on the returned Promise object.
1 2 3 4 5 6 7 8 9 10 11 |
function F() { console.log(`-- F --`); getWebcast().then( (result)=> { console.log('-- result of fetch in F --'); console.log(result); }); // when using Promises, this line will be executed async console.log(`using Promises -- end of F --`); } |
So now, you’ll see that the single thread will execute getWebcast’s returned Promise a bit,
then continue execution and log. Goes back and process Promise a bit, then keep going on to the next execution.
Eventually, when the Promise in F is done, the thread goes into the then and then logs.
Hence, note that the execution continues right after the start execution of our Promise.
results:
— F —
— getWebcast —
using Promises — end of F —
end of script…
wait 2 seconds
— result of fetch in F —
{data: “payload”}
Using async/await
Now that we’ve seen how Promises work, let’s look at async await.
await is only valid in async function
In order to use await, you must wrap it inside of an async function. You can also use Promises in async functions.
However, there is a minor difference. With async/await, the execution will stop at ‘await’ within the async function.
Execution will continue in the async If and Only If the await has been executed.
However, execution OUTSIDE of the async function will be asynchronously processed. Let’s take a look at an example.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
function getWebcast () { console.log('-- getWebcast --'); // async function requires a Promise object to be returned return new Promise( (resolve, reject) => { setTimeout( () => { resolve({data: 'payload'}) }, 2000); }); } async function F() { console.log(`-- F --`); // 2) await #2 let result = await getWebcast(); console.log('-- result of fetch in F --'); console.log(result); // but when using away, this line won't get executed until after the awai is done console.log(`using Await -- end of F --`); } F(); console.log('end of script...'); |
— F —
getWebcast —
end of script…
wait 2 seconds
result of fetch in F —
{data: “payload”}
using Await — end of F —
So as you can see in the async function F, the execution actually stops at getWebcasts()
It does not go onto the three logs.
But when function F does execute it, the thread will asynchronously execute the log ‘end of script…’ after F().
This is obvious in the output as it is printed to the console, and then we simulate the 2 second wait.
After the 2 second wait, we then see the rest of the code (AFTER await in the async function) get executed.
If you want everything to run top down, without the thread running down the execution line on printing “end of script…” when its waiting for the 2 seconds…then simply put await in front of F:
1 |
await F(); |
This ensures that we will always wait until an async operation is done before we move on.
This applies also to when we use then also.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
async function F() { console.log(`-- F --`); // 1) await #1 await getWebcast().then( result => { console.log('-- result of fetch in functionalityOne --'); console.log(result); }); // but when using away, this line won't get executed until after the awai is done console.log(`using Await -- end of F --`); } F(); console.log('end of script...'); |
output:
— F —
— getWebcast —
end of script…
wait 2 seconds
result of fetch in functionalityOne —
{data: “payload”}
using Await — end of F —
In an Async function, execution must finish on Await, before it moves on to the rest of the async function code. However, it will continue asynchronous code outside of the Async function.
…in other words, await BLOCKS the code execution WITHIN the async function.
Additional Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
console.log(`-- start of execution --`); // 1) async function f() { console.log("f - start of f()"); //4 ) let promiseObj = new Promise((resolve, reject) => { console.log("Promise - starting executor"); // 5) // 6 setTimeout( () => resolve("Data fetched..."), // 10 The promise has been resolved! 2000); console.log("Promise - finished executor"); // 7) }); // 8) WE NOW NEED TO WAIT HERE BECAUSE OF THE "AWAIT". However // execution will continue further at 9) let result = await promiseObj; // wait till the promise resolves (*) console.log("f - result is: " + result); // 11) Since the promise was resolved, we continue here. console.log("f - end of f()"); // 12 } console.log("right before calling f()"); // 2) f(); //3) // 9) because async f() is waiting...JS's execution continues further. console.log("...future code executes...") |
If you do not return a Promise, async function will return a Resolved Promise
1 2 3 4 5 6 7 8 |
async function F() { return 100; } F().then( res => { console.log('result'); console.log(res); // 100 }) |
As for async operations, it won’t work here because the Promise here is resolved already.
If you want to do a future resolve, make sure to create your own Promise, and resolve where you want.