Did you know that await can work without promises
awaiting a non promise function or method
Generally we use async/await
with promises.
Let’s see this with an example:
const fetch = ()=> {
return new Promise(function(resolve) {
setTimeout(()=> {
resolve('Done');
}, 3000);
});
}
async function getList() {
const data = await fetch();
console.log(data);
}
In above code fetch
is returning a promise which will be resolved after 3 seconds
and we are awaiting
fetch, and once the execution of fetch
is completed after 3 seconds
, console.log(data)
will be executed.
This is the normal flow which we have been used to.
But this isn’t mandatory that we have to use await
with a function returning promise.
Let’s see few examples:
async function withoutPromise() {
const count1 = 5;
const count2 = await 5;
console.log(data);
}
withoutPromise();
The above code is completely fine. There is no difference between the two lines. const cont1=5
and const count2 = await 5
, at-least theoretically.
But that’s not the whole picture.
Let’s try to understand what difference does await
word is making in reality:
console.log('A');
(async function() {
const x = await 5; // remove await to see A,C,B
console.log("C");
})();
console.log("B");
// what will be printed in console?
.
.
In the console, following will be printed in the order:
A
B
C
why so? (Magic of await)
Because if the function
which we are awaiting
does not return a promise, await
will wrap it inside a promise and it will be executed by web apis
just like a normal promise and will be treated as a Micro Task
.
Another Fact about await
There is another interesting thing about await.
i.e., await
does not only work on instanceof Promise
but on every object which contain a method corresponding to key called then
.
await
will auto wrap the then method inside a promise
and provide two methods resolve
and reject
automatically.
function thenable() {
return {
then: function() {
// your code
}
}
}
async function test() {
const data = await thenable();
}
In above code, thenable
function returning an object which contains then
as key.
await
will wrap it inside a promise and gives us resolve
and reject
methods as an argument.
It’s on us to call resolve
or reject
.
If we don’t call it, then the await will keep on waiting.
function thenable() {
return {
then: function(resolve, reject) {
// resolve and reject will only come, it thenable is used with await.
resolve('Done');
// It's on developer to call the resolve.
}
}
}
async function test() {
const data = await thenable();
console.log(data); // It will log 'Done'
}
test();
Another code snippet to show that we can directly await
an object
having then
key as a method.
async function test(){
await { then: function() {} };
console.log("I will never be executed");
}
console.log(1);
test();
console.log(2);
Here in the console 1
and 2
will be logged, because we aren’t resolving or rejecting the promise, the console will never get chance to be executed, and the program will indefinitely be awaiting.
As an exercise can you make I will never be executed
to be logged in console by correcting the above code?
So that’s all about the word await
. I hope it made you to learn something new about JS.