Asynchronous iteration allow us to iterate over data that comes asynchronously, on-demand. Like, for instance, when we download something chunk-by-chunk over a network. And asynchronous generators make it even more convenient.
Let’s see a simple example first, to grasp the syntax, and then review a real-life use case.
Recall iterables
Let’s recall the topic about iterables.
The idea is that we have an object, such as range here:
let range = {
from: 1,
to: 5
};
…And we’d like to use for..of loop on it, such as for(value of range), to get values from 1 to 5.
In other words, we want to add an iteration ability to the object.
That can be implemented using a special method with the name Symbol.iterator:
- This method is called in by the
for..ofconstruct when the loop is started, and it should return an object with thenextmethod. - For each iteration, the
next()method is invoked for the next value. - The
next()should return a value in the form{done: true/false, value:<loop value>}, wheredone:truemeans the end of the loop.
Here’s an implementation for the iterable range:
let range = {
from: 1,
to: 5,
[Symbol.iterator]() { // called once, in the beginning of for..of
return {
current: this.from,
last: this.to,
next() { // called every iteration, to get the next value
if (this.current <= this.last) {
return { done: false, value: this.current++ };
} else {
return { done: true };
}
}
};
}
};
for(let value of range) {
alert(value); // 1 then 2, then 3, then 4, then 5
}
If anything is unclear, please visit the chapter Iterables, it gives all the details about regular iterables.
Async iterables
Asynchronous iteration is needed when values come asynchronously: after setTimeout or another kind of delay.
The most common case is that the object needs to make a network request to deliver the next value, we’ll see a real-life example of it a bit later.
To make an object iterable asynchronously:
- Use
Symbol.asyncIteratorinstead ofSymbol.iterator. - The
next()method should return a promise (to be fulfilled with the next value).- The
asynckeyword handles it, we can simply makeasync next().
- The