DEV Community

loading...
Cover image for Await, Promises & Promise Methods

Await, Promises & Promise Methods

Jacob Evans
FullStack Software Engineer @ Cloudflare | Air Force Veteran | Hardware Enthusiast | Outdoorsman | OSS Enthusiast & Contributor
・3 min read

tl;dr finished up talking about await and execution blocking.
Went over why Promise is still valuable and powerful even if not using
.then()

Await

So a caveat to await, it's technically limited to working inside async functions. This is by design, there are workarounds but stick with the enforced practice at first; in the end, coding is about experimenting and breaking/making things 😆

Pausing Execution

So the keyword await pauses execution of async function until the Promise is settled... In other words, until something returns from
const data = await APICall() and data variable now contains the returned value of the resolved Promise. If the Promise rejects, an exception is thrown. Though await alone doesn't gracefully handle errors we can make error boundaries, I prefer to use try/catch blocks.

Parallel

This is accomplished with Promise.all([call1, call2])
Though we talked a little on the ability to resolve multiple asynchronous calls I'll go over it again. So rather than waiting for each one to resolve after the last. This in turns takes away the more synchronous-like behavior observed with the execution blocking with await alone. Neither is better than the other, but have their benefits and drawbacks for various use cases.

Examples

// Pausing Execution - numbers indicate milliseconds for data to return
async function somethingMakingApiCall() { 
 const dataFirst = await callFirst(10) // pause 10ms
 const dataSec = await callSec(1) // pause 1ms
 const dataThird = await callThird(5) // pause 5ms

// 16ms later reaches this return with resolved data.
return [dataFirst, dataSec, dataThird]
}
// The order of data returned is irrelevant, // execution order is the same. 
console.log(somethingMakingApiCall()) // [ 10ms, 1ms, 5ms ]

// Parallel -- What's the benefit?
async function somethingMakingApiCall() { 
// All calls are executing in Promise.all() so no pause for each occurs.
const [ first, sec, third ] = await Promise.all([ callFirst(10), callSec(10), callThird(10) ])

// 10ms later the function execution
// reaches return with resolved data.
return [ first, sec, third ];
}

console.log(somethingMakingApiCall()) // 10ms, 10ms, 10ms
Enter fullscreen mode Exit fullscreen mode

Promises

I have already mentioned Promise.all() in this and the previous article. so I will briefly mention fail-fast if the call first(10) had rejected then the whole thing immediately breaks out and throws that rejection. This can be a gotcha or a powerful feature depending on the situation. An example could be, 2nd & 3rd call rely on 1st call succeeding, so if it rejects no need to waste time with two more calls 😁
## Promise API
So there are plenty of Promise methods which you can find on MDN

Noteworthy ones with async/await in my opinion:

  • Promise.all()
    "On some computers, they may be executed in parallel, or in some sense concurrently, while on others they may be executed serially. For this reason, there must be no dependency in any Promise on the order of execution of the Promises." - MDN related article
    I have mentioned previously its quasi concurrency/parallelism this excerpt describes the reason why very well.

  • Promise.race()
    "...method returns a promise that fulfills or rejects as soon as one of the promises in an iterable fulfills or rejects, with the value or reason from that promise." - MDN related article

  • Promise.any()
    "takes an iterable of Promise objects and, as soon as one of the promises in the iterable fulfills, returns a single promise that resolves with the value from that promise." - MDN related article

Discussion (0)