JS Tip of the Day: Awaiting Non-promises

Awaiting Non-promises
Version ES2017
Level: Intermediate

Normally, await is used to wait for the completion of a promise. When encountered, the current async function will pause its execution and only resume once the promise being awaited is fulfilled. But it’s also possible to use await with non-promises. In doing so, the await will implicitly wrap the value in a resolved promise.

async function example () {
    await 0; // 0 treated as Promise.resolve(0)
}

It’s likely uncommon that you’d want to await a non-promise, though there may be cases where you have a value which may or may not be a promise. Instead of having to perform a check on that value to see, you can simply await it directly.

async function waitFor (anyValue) {
    let result = await anyValue;
    return result;
}

waitFor(4)
    .then(value => console.log(value)); // 4
    
let promised4 = new Promise(resolve => {
    setTimeout(() => resolve(4), 500);
});
waitFor(promised4)
    .then(value => console.log(value)) // 4

Awaiting an arbitrary value this way can also be used to delay the execution of code. Once an await is reached, even if the value is already available (as a non-promise or a promise that’s already resolved), the execution of the async function is still paused and the rest of the call stack will run out until it picks up again.

async function wrapWork () {
    console.log('Start work!');
    await 0;
    console.log('Work complete!');
}

wrapWork();
console.log('Doing all the work...');
/* logs:
Start work!
Doing all the work...
Work complete!
*/

More info: