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
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 articlePromise.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
Top comments (0)