Introduction
Generators and iterators are features introduced in ECMAScript 6 (ES6), which is also known as ES2015. These features provide a new way to iterate over collections of data and to generate values on the fly.
Generators allow you to define functions that can be paused and resumed, while iterators provide a standardized way to traverse collections of data. Let’s dive deeper into these concepts.
Generators
A generator function is a special type of function that can be paused and resumed at any time, allowing you to generate a sequence of values on the fly.
To define a generator function, you use the function*
syntax (the asterisk distinguishes it from a regular function).
Inside the generator function, you use the yield
keyword to pause the function and return a value to the caller.
For example, let’s define a simple generator function that generates a sequence of numbers:
In this example, when we call the numberGenerator
function, it will return an iterator that we can use to iterate over the sequence of numbers. To do this, we use the next method of the iterator, like this:
As you can see, each time we call the next method of the iterator, the generator function resumes execution and returns the next value in the sequence.
Iterators
An iterator is an object that provides a standard way to traverse a collection of data. In JavaScript, iterators are defined by the Iterable and Iterator protocols.
The Iterable protocol defines a method that returns an Iterator object, while the Iterator protocol defines a next method that returns an object with two properties: value
and done
.
To make an object iterable, you define a method on the object that returns an iterator. This method is called [Symbol.iterator]
, and it should return an object that conforms to the Iterator protocol.
For example, let’s define a simple iterable object that generates a sequence of numbers:
In this example, we define a generator function inside the [Symbol.iterator]
method to generate the sequence of numbers. We can now use a for...of
loop to iterate over the sequence:
Real life example
Suppose you are building a web application that allows users to upload and manage images. You want to implement a feature that automatically resizes the images to a certain size before saving them to your server.
To accomplish this, you can use generators and iterators to process the images in a stream-like fashion, allowing you to efficiently resize and save the images one by one.
First, you create a generator function that retrieves the uploaded images from the client-side and yields each image as a data URI
Next, you create an iterator function that retrieves each image data URI from the generator and resizes it using a library like sharp
or whatever is your preferred library/API
Finally, you create a function that saves each resized image to your server
By using a generator and an iterator, you can easily process each uploaded image in a stream-like fashion, without having to load all the images into memory at once.
This can be especially useful if you are dealing with a large number of images, as it allows you to process them efficiently and without running into memory issues.
Conclusion
Generators and iterators are powerful tools that provide a new way to work with collections of data in JavaScript. Generators allow you to generate a sequence of values on the fly, while iterators provide a standardized way to traverse collections of data.
By using these features, you can write more efficient and scalable code in JavaScript.