JavaScript Async Await Sequencing and Execution Masterclass

Pro Members Only

This lesson is available if you have an active subscription.

Alternatively, some member might be able to gift it to you.

If you already have a subscription, you can sign in.

Professional Modern JavaScript Lessons

1.Course Intro
free
⏱️ 1:13
2.Setup & Tooling
free
⏱️ 3:32
3.Debugger Statements and Breakpoints
free
⏱️ 2:17
4.Primitive Data Types and Values
free
⏱️ 3:06
5.JavaScript Variables - let and const
free
⏱️ 4:50
6.Comments in JavaScript
free
⏱️ 2:55
7.JavaScript Identifer Naming
free
⏱️ 2:52
8.Using TypeScript
free
⏱️ 4:26
9.JavaScript String Masterclass
free
⏱️ 9:29
10.JavaScript Boolean Type
⏱️ 6:45
11.Missing Guide to JavaScript Numbers
⏱️ 15:28
12.JavaScript Objects Demystified
⏱️ 13:33
13.Functions in JavaScript
⏱️ 20:25
14.JavaScript Arrays Masterclass
⏱️ 22:31
15.JavaScript If Else Statements and Best Practices
⏱️ 6:13
16.JavaScript Conditional Expressions
⏱️ 8:38
17.JavaScript Loose vs Strict Equality
⏱️ 4:02
18.Truthy vs Falsy in JavaScript
⏱️ 3:44
19.Concept of JavaScript Nullish and Unification
⏱️ 5:51
20.JavaScript Classes - Object Oriented Programming
⏱️ 10:30
21.JavaScript Error Handling and Exceptions
⏱️ 13:21
22.JavaScript Nullish Operators
⏱️ 5:48
23.JavaScript Switch Statement Masterclass
⏱️ 8:07
24.JavaScript For Loop Iteration Simplified
⏱️ 10:59
25.JSON Masterclass
⏱️ 7:59
26.JavaScript While and Do While Loops
⏱️ 2:52
27.JavaScript Date and Time Simplified
⏱️ 13:16
28.this in JavaScript
⏱️ 12:04
29.JavaScript Tagged Templates Masterclass
⏱️ 5:48
30.Promises in JavaScript
⏱️ 10:01
31.JavaScript Async Await Masterclass
⏱️ 9:00
32.JavaScript Symbols Demystified
⏱️ 7:25
33.JavaScript Iterators and Iterables
⏱️ 8:50
34.JavaScript Generators Simplified
⏱️ 9:17
35.JavaScript Prototype - The Secret Guide
⏱️ 11:21
36.JavaScript Set Builtin Data Structure
⏱️ 9:52
37.JavaScript Map Builtin - HashMap Magic
⏱️ 10:38
38.JavaScript Deferred Promise Pattern - withResolvers
⏱️ 3:35
39.Cloning and Deep Copying in JavaScript
⏱️ 3:14
40.JavaScript Async Await Sequencing and Execution Masterclass
⏱️ 10:31
41.JavaScript Memory Management Masterclass
⏱️ 5:26
42.JavaScript WeakMap Demystified
⏱️ 8:58
43.JavaScript bigint Masterclass
⏱️ 5:35
44.JavaScript WeakSet Explained with Examples
⏱️ 7:47
45.JavaScript Regular Expressions Masterclass
⏱️ 17:54
46.JavaScript Weak References Demystified
⏱️ 5:29
47.JavaScript Memory Leaks Demonstrations and Fixes
⏱️ 6:01
48.Semicolon Free Coding in JavaScript
⏱️ 3:46
49.JavaScript Modules Masterclass
⏱️ 11:36

JavaScript Async Await Sequencing and Execution Masterclass

Subscription Required

You must have an active subscription to access this content.
If you already have a subscription, you can sign in.

Setup

export const pass = (value) => new Promise(
(res) => setTimeout(() => res(value), 1000)
);

export const fail = (errorMessage) => new Promise(
(_, rej) => setTimeout(() => rej(new Error(errorMessage)), 1000)
);

main();

async function main() {
try {

} catch (err) {
console.log('Rejected:', err.message);
}
}

Sequential

const alpha = await pass('alpha');
console.log(alpha);

const beta = await pass('beta');
console.log(beta);

const charlie = await pass('charlie');
console.log(charlie);

const delta = await pass('delta');
console.log(delta);

Promise.all

const alphaPm = pass('alpha');
const betaPm = pass('beta');
const charliePm = pass('charlie');

const [alpha, beta, charlie] =
await Promise.all([alphaPm, betaPm, charliePm]);
console.log(alpha, beta, charlie);

Promise.allSettled

const alphaPm = pass('alpha');
const betaPm = fail('beta');
const charliePm = pass('charlie');
const result = await Promise.allSettled([alphaPm, betaPm, charliePm]);
console.log(result);

const [alphaResult, betaResult, charlieResult] = result;
if (alphaResult.status === 'fulfilled') {
console.log(alphaResult.value); // 'alpha'
}
if (betaResult.status === 'rejected') {
console.log(betaResult.reason); // Error: beta
}

Promise.any

try {
const alphaOnePm = pass('alpha one'); // or fail
const alphaTwoPm = pass('alpha two'); // or fail
const firstFulfilled = await Promise.any([
alphaOnePm,
alphaTwoPm,
]);
console.log(firstFulfilled);
} catch (err) {
console.log('AggregateError:', err instanceof AggregateError);
console.log('message:', err.message);
console.log('errors:', err.errors);
}

Promise.race

try {
const alphaOnePm = pass('alpha one');
const alphaTwoPm = pass('alpha two');
const fulfilled = await Promise.race([
alphaOnePm,
alphaTwoPm,
]);
console.log('Fastest Fulfilled:', fulfilled);
} catch (err) {
console.log('Fastest Rejected:', err.message);
}
javascript
typescript
react
playwright

Enjoy free content straight from your inbox 💌

No spam, unsubscribe at any time.

Transcript

00:00

When it comes to asy programming within JavaScript, we have a lot of options on how we can manage multiple tasks using promises. Let's set up a simple structure that will help us demonstrate the different flows. We are not going to do anything complicated. We are going to give it very simple. So here is a utility called pass, which takes a value and then returns promise, which we resolve to that value after one second, and we create a similar utility called fail, which takes an error message and then returns a promise which we will then reject with an error pointing to that error message. After one second, we are going to be demonstrating a code by executing an async main function and

00:38

within the main function we have a very simple try catch to demonstrate any promise rejection that might happen. Now the work that we are doing in our tasks pass and fail is just waiting for a timeout, but it might as well be any async work that you can think of like a backend a p I call. Now that we have this careful ready, let's discuss the different execution options. The simplest execution of Async and JavaScript is to simply await each call as you make it, and this results in a sequential flow where tasks are executed one after another. As an example, we execute a task which will eventually pass with the value alpha and we do not

01:13

continue program execution till this task resolves by using the await keyword. Once it resolves, we get the value of alpha and we log that to the console and we can do a similar thing as many times as we want. We can execute other tasks, beta, Charlie and Delta, and then await the results with the await keyword. As soon as we execute them, we wait for alpha till resolves, then we wait for beta, then we wait for Charlie, then we wait for Delta and all of them do succeed. In this particular case, we know that at any point if any of these promises result in a rejection, for example, we fail Charlie,

01:48

then the await results in a standard throw of the error which we are catching. And when we run this code that is exactly what we see, alpha and beta pass, then Charlie throws an error and we never execute. Tel series execution is pretty easy to understand and you can pretty much use your standard synchronous mindset when working with code that executes in sequence. The hard opposite of a sequential flow is parallel execution and with JavaScript we can actually fire off all of the Async work in parallel and analyze the results using built-in promise static methods. JavaScript comes with a number of such methods and the first one we will look at

02:22

is promised all as this is the most common one that you will use. So instead of awaiting the results individually, we just fire off the work and then store the results into different promise variables. This means any of the tasks within the past function, which is just timeout has already started and they will pretty much complete at the same time. To get the fulfilled result of all of these promises, we can use the built-in static method called Promise dot All. It can take an array of promises as an input and then combines them into a single promise.

02:54

We can await this promise to get an array of the resolved values of the original promises. So since our promises resolved to the strings alpha, beta and Charlie, if we execute the code, that is exactly what we see. You can think of promise to all as the parallel B f F of the sequential flow and just like in a sequential flow, a promise failure on any of the sequence results in a throw at that point and we jump straight into the rejection promise dot all will also reject the combined promise if any of the individual past and promises fail. So here we are failing beta,

03:27

so the combined promise will fail with the error of beta and that is what we see in the program. Output Promise dot all will result in a rejection immediately after any single promise in the argument settles on a rejection. But if you want complete knowledge about the fates of all of the promises in the input, that is where promise dot all settled comes in. Consider the simple example where we have three promises. The first one will pass with the value alpha, the second one will fail with the recent beta and the third one will pass with a value. Charlie, since we are not awaiting any of these,

04:00

these tasks have already started executing in parallel the promise that all settled function can take these promises and then combine them into a single promise which will resolve as soon as all of these promises have settled on their faiths, the resulting promise will always resolve into a single array. So let's just log it out to understand more about its structure. The individual items in the result array indicate the final status of the original inputs. The status field will either be fulfilled if the promise got fulfilled or it'll be rejected if the promise got rejected. Additionally, if it got fulfilled,

04:34

it'll have a value and if it got rejected it'll have a reason. Field Alpha got fulfilled with the value Alpha Beta got rejected with an error object with the reason Beta and Charlie got fulfilled with the value. Charlie, now that we understand the structure of the result array, it is actually quite easy to destructure it into individual results and as we have seen, alpha result of status will be fulfilled, which means that it'll have a value which is alpha. And since beta result of status is going to be rejected, it means that it'll have another member called Reason, which will be the error object that Beta was rejected with.

05:09

We use Promise at all and promise at all settled when the promises are distinct tasks with their own results. But sometimes we use Parallelization for a set of similar tasks. An example use case would be network redundancy where we make the same call to two backends and really only care if any of them succeed. For this we have the builtin promise any we fire off a task to one server alpha one and we fire off the same task alpha to another server. Alpha two, we don't really care if any of these fail. All that we really care about is whichever one passes first.

05:42

And for that purpose we have the built-in Promise any it takes the two promises and combines them into a single promise which will resolve as soon as any of these get fulfilled. We log out the value of whatever got fulfilled and just in case nothing Gets fulfilled, the promise will actually reject. And we can catch that with a simple catch. And this particular error will be an instance of an aggregate error because it actually combines the errors of all of the promises that we passed in. It'll have a message property which is going to be simply all promises were rejected and it'll also have an errors property which are the actual rejections

06:18

from the individual promises. Let's do a few walkthroughs to understand Promise Any a bit better. Right now, both Alpha one and Alpha two are going to pass, and since we kicked off Alpha one first, that is the one that will succeed first and that is indeed the result that we get for first fulfilled. If however, alpha one were to fail, then promise do any will keep waiting till alpha two settles and of course it'll pass. So that is what we get for first fulfilled. If however, all of the promises that we are passing to promise do any get rejected, then the resulting promise will also get rejected. And as we have mentioned,

06:52

you will see an instance of aggregate error with the message. All promises were rejected and the errors point to the individual rejection reasons. Sometimes you might run the same task multiple times in parallel. When we are trying to optimize for speed, one instance of the task might complete faster and we'd rather hear back from whoever can get back to us the quickest. And for these kinds of use cases, we have the appropriately named Promise race method. We fire off two tasks, alpha one and Alpha two, and of course we don't await them because we want to run them in PE and we really only care about who can get back to us the fastest.

07:27

These tasks might be running into different corners of the world and we really care about getting the result as quickly as possible, which is why we are starting two tasks instead of calling to just one machine. And the built-in JavaScript method Promise dot raise does just that. It takes a number of promises and then combines them into a single promise which will resolve as soon as any of the input promises resolves. So if the fastest among Alpha one and Alpha two get fulfilled, we will get back the fulfilled value and if it results in a rejection, we will get a rejection which we tackle with the try Catch right now.

08:01

We know that both of these promises will pass, and since we kick off alpha one first, that is the thing that will actually get fulfilled and we see that in the program output. This means that even if alpha two were to fail, it wouldn't change our outcome because alpha one will already be fulfilled before Alpha two gets the chance to fail. And if you run this code, that is exactly what we see in the program output. We are still getting fulfilled by alpha one. So with promise to trace the fate is completely dependent upon whichever promise settles first. If the first promise were to settle in a rejection, then the resulting promise will also result in a rejection,

08:37

and that is exactly what we see in the program output. I understand that keeping the various promise utility methods in your head can be a bit challenging. So here's a quick recap and a reference that you can always revisit whenever in doubt. First up, we have the standard sequential flow. We simply await every single Promise as soon as we get it, and this means that the program doesn't execute till that promise is resolved. And this is the simplest one to understand. The alternative are parallel flows, and the one thing that is common across all of them is that we do not await the promise after we start the task.

09:10

There are various ways we can combine the parallel task results and the simplest one is promised do all, which will simply wait for all of them to get fulfilled. And if they're all fulfilled, we get back an array of fulfilled values. Otherwise we get the rejection from the first promise that gets rejected. If you want more lower level control and just want the fates of all of the promises into a simple array, then promise all settled is your friend. It gives us back an array where each item contains the individual promises, status of value of it got fulfilled, or a reason if it got rejected. If you are keeping your fingers crossed that some promise might get fulfilled,

09:47

then promise dot any is your friend. An example use case would be something like network redundancy. You know that some things might fail, but you hope that something will at least pass. And finally, if you just really care about the fastest promise to come back to you, then we have Promise Race. If the fastest promise gets fulfilled, then the result gets fulfilled. If the fastest promise gets rejected, then the result gets rejected. An example use case would be duplicated work across different machines so you don't have to do some upfront optimization to figure out which machine is likely to give you the answer faster.

10:21

I hope you enjoyed this tutorial on how you can manage multiple promises effectively in JavaScript. As always, thank you for joining me and I will see you in the next one.

Professional Modern JavaScript

Professional Modern JavaScript

1.Course Intro
free
⏱️ 1:13
2.Setup & Tooling
free
⏱️ 3:32
3.Debugger Statements and Breakpoints
free
⏱️ 2:17
4.Primitive Data Types and Values
free
⏱️ 3:06
5.JavaScript Variables - let and const
free
⏱️ 4:50
6.Comments in JavaScript
free
⏱️ 2:55
7.JavaScript Identifer Naming
free
⏱️ 2:52
8.Using TypeScript
free
⏱️ 4:26
9.JavaScript String Masterclass
free
⏱️ 9:29
10.JavaScript Boolean Type
⏱️ 6:45
11.Missing Guide to JavaScript Numbers
⏱️ 15:28
12.JavaScript Objects Demystified
⏱️ 13:33
13.Functions in JavaScript
⏱️ 20:25
14.JavaScript Arrays Masterclass
⏱️ 22:31
15.JavaScript If Else Statements and Best Practices
⏱️ 6:13
16.JavaScript Conditional Expressions
⏱️ 8:38
17.JavaScript Loose vs Strict Equality
⏱️ 4:02
18.Truthy vs Falsy in JavaScript
⏱️ 3:44
19.Concept of JavaScript Nullish and Unification
⏱️ 5:51
20.JavaScript Classes - Object Oriented Programming
⏱️ 10:30
21.JavaScript Error Handling and Exceptions
⏱️ 13:21
22.JavaScript Nullish Operators
⏱️ 5:48
23.JavaScript Switch Statement Masterclass
⏱️ 8:07
24.JavaScript For Loop Iteration Simplified
⏱️ 10:59
25.JSON Masterclass
⏱️ 7:59
26.JavaScript While and Do While Loops
⏱️ 2:52
27.JavaScript Date and Time Simplified
⏱️ 13:16
28.this in JavaScript
⏱️ 12:04
29.JavaScript Tagged Templates Masterclass
⏱️ 5:48
30.Promises in JavaScript
⏱️ 10:01
31.JavaScript Async Await Masterclass
⏱️ 9:00
32.JavaScript Symbols Demystified
⏱️ 7:25
33.JavaScript Iterators and Iterables
⏱️ 8:50
34.JavaScript Generators Simplified
⏱️ 9:17
35.JavaScript Prototype - The Secret Guide
⏱️ 11:21
36.JavaScript Set Builtin Data Structure
⏱️ 9:52
37.JavaScript Map Builtin - HashMap Magic
⏱️ 10:38
38.JavaScript Deferred Promise Pattern - withResolvers
⏱️ 3:35
39.Cloning and Deep Copying in JavaScript
⏱️ 3:14
40.JavaScript Async Await Sequencing and Execution Masterclass
⏱️ 10:31
41.JavaScript Memory Management Masterclass
⏱️ 5:26
42.JavaScript WeakMap Demystified
⏱️ 8:58
43.JavaScript bigint Masterclass
⏱️ 5:35
44.JavaScript WeakSet Explained with Examples
⏱️ 7:47
45.JavaScript Regular Expressions Masterclass
⏱️ 17:54
46.JavaScript Weak References Demystified
⏱️ 5:29
47.JavaScript Memory Leaks Demonstrations and Fixes
⏱️ 6:01
48.Semicolon Free Coding in JavaScript
⏱️ 3:46
49.JavaScript Modules Masterclass
⏱️ 11:36