iterator is used quite often, e.g. in spread operator, for/of-loop, in deconstructing, etc. But they are hidden. I wonder whether there are use cases where you would actively use the knowledge of how to implement an iterator?
For example, iterating over an array using an iterator is over complicated, as you can see below, and I wouldn't know why someone would implement an iterator by himself:
function arrayIterable(arr = []) {
let index = 0;
const len = arr.length;
const arrayIterator = {
next: () => {
let result;
if (index === len) {
return { value: arr[index], done: true };
}
result = { value: arr[index], done: false }
index++;
return result;
}
};
return arrayIterator;
}
const myArr = ['a','b','c','d'];
let iter = arrayIterator(myArr);
let result = iter.next();
while (!result.done) {
console.log(result.value);
result = iter.next();
}
It's handy if you want to operate on a dataset lazily. A stream, a file, a database, you move from one row/record to the other and advance the iterator. No need to keep the history in memory.
Since you don't have to maintain the whole source in memory, you can also handle the case of infinite data sources.
The biggest win of an iterator is at the client side. In a pre-iterator era code you are usually given an array-like object that exposes the indexing. However, in a modern code you could be given an iterator which means the client handles more general results with the same code. Consult the discussion under this question for an example case.
I don't think the knowledge of how it is implemented would be used to actually iterate over the thing. There is no advantage to that over using a for of loop.
But suppose you are building a JavaScript library, such as the Node.js driver for a MongoDB database. You want to make it easy to query the database and loop over the results. You implement the iterable protocol and then people can do this:
const cursor = queryDatabase(<some query>)
for (let doc of cursor) {
// do something with doc
}
In fact, the MongoDB Driver really does do this (except that they implement an async iterator).
EDIT: Note the benefit of using the iterator protocol over returning an array-like object from queryDatabase(). In MongoDB specifically, the cursor does not hold all of the results. It is a handle, and results of the query can be obtained by calling cursor.next()
The problem with having to call cursor.next() is that it is quite clunky, as you pointed out in the question. Yet it is good because not all of the results need to be fetched from the database, of which there could be thousands. So the iterator protocol is a way to keep the benefits of cursor.next() without having to deal with the ugly syntax.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With