Iterate Asynchronously with the for-await-of Loop

Marius Schulz
InstructorMarius Schulz

Share this video with your friends

Send Tweet
Published 5 years ago
Updated 3 years ago

We finish the course by looking at asynchronous iterators, a generic data access protocol for asynchronous data sources. This asynchronous iteration scheme is built on top of a new for-await-of loop and async generator functions.

[00:00] Here, I have a simple generator, which yields the values 1, 2, and 3. Within the main function, I can use the for...of loop to iterate over every value produced by the generator. I'll add a log statement here, just to make sure everything is working.

[00:17] Let's run the program, and yes, we see 1, 2, and 3 printed to the console. Let's now see how we can make this generator function asynchronous.

[00:29] First, I'm going to add the async keyword. Within the generator, I'll add some artificial delays to simulate long-running operations. The delay function doesn't exist yet. I'll add it above the generator function. It simply returns a new promise, which is resolved after a given number of milliseconds.

[00:50] I will also make the main function asynchronous, and I'll add the await keyword right before the opening parenthesis of the loop. This is a for...await...of loop, a new variation of the for...of loop. It's used for asynchronous iteration.

[01:07] There are two more things I need to do before I can run this program. First, I will polyfill the async iterator symbol. Here, I'm just monkey-patching it, but in a real application, you would want to use a proper polyfill.

[01:21] Second, I need to transpile this JavaScript file because my current Node version doesn't support async iteration yet. To do this, I have created a little npm script, which invokes my transpiler. I am now ready to run the transpiled program.

[01:35] You want to pay close attention to the timing. All right, here we go.

[01:46] One more time for the dramatic effect.

[01:52] Notice how the values are printed one after the other, with a delay of one second in between each of them. This is because our asynchronous generator yields three promises, instead of three plain objects.

[02:04] Our for...await...of loop down here gets back the first promise, and then waits until that promise is resolved. It only then resumes the generator. The generator then returns a second promise, and so on.

[02:17] I want to close off this lesson by showing roughly what happens in our main function. First, the for...await...of loop instantiates the generator. We then enter a while loop. Within that loop, we await the promise returned by generator.next, and then we deconstruct the result into its value and done properties.

[02:38] If we are done, we break out of the loop and stop the iteration. After this, if statement comes the loop body. In our case, we log the value property to the console. If I have done everything correctly, we should still see the numbers 1, 2, and 3 printed to the console, and we do.

Ben Diuguid
Ben Diuguid
~ 4 years ago

Awesome and concise course! I wanted to see what your babel configuration was and maybe the repo is not public? But the link gives me a 404.

Marius Schulz
Marius Schulzinstructor
~ 4 years ago

The repo link should work now, thanks for the hint! I'm using TypeScript rather than Babel in this lesson; here's the tsconfig.json.

Marius Schulz
Marius Schulzinstructor
~ 4 years ago

Glad you liked them, thanks for watching!

Matteo Hertel
Matteo Hertel
~ 4 years ago

I noticed that after the refactor of the for await loop you still ran the async.js in the dist folder, the one that has been transpiled, was it intended behaviour (you ran the transpiler behind the scene) or not? thanks for the amazing course, I loved every bit of it!

Marius Schulz
Marius Schulzinstructor
~ 4 years ago

Exactly, I was running the TypeScript compiler in watch mode in the background. While recording, I actually had to check that I was running the updated code by prepending some other log statement. :)

Bart
Bart
~ 4 years ago

by the end you forgot to run build again, instead you run existing version from the dist. I guess it wont change the final result ;)

software
software
~ 3 years ago

by the end you forgot to run build again, instead you run existing version from the dist. I guess it wont change the final result ;)

+1

~ 3 years ago

Hey Marius, Marius here ;) So it is indeed a little confusing if the main() is used or the already transpiled one. I guess you've answered it above but it should be made clear somehow in the video. can't you add an overlay text comment or something?