In JavaScript, a Generator function is a special kind of function that can pause its execution and resume it later. This allows you to write code that looks synchronous but actually executes asynchronously, making it useful for tasks like iterative processing or generating sequences of values.
To create a new Generator object in JavaScript, you first need to define a Generator function. This function is marked by the function*
syntax, which tells JavaScript that it’s a generator function. Inside this function, you can use the yield
keyword to pause execution and return a value to the caller. The caller can then resume execution by calling the generator’s next()
method.
Here’s an example of a simple generator function that generates an infinite sequence of numbers starting from zero:
function* numberGenerator() {
let i = 0;
while (true) {
yield i;
i++;
}
}
This function starts with an initial value of i = 0
and enters an infinite loop. In each iteration, it yields the current value of i
using the yield
keyword and then increments i
by one.
To create a new Generator object based on this function, you simply call the function like a regular function and assign the result to a variable:
const generator = numberGenerator();
This creates a new Generator object based on the numberGenerator
function and assigns it to the variable generator
. The generator is not executed immediately when you create it. Instead, it starts executing when you call its next()
method.
console.log(generator.next()); // { value: 0, done: false }
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
The next()
method returns an object with two properties: value
and done
. The value
property contains the value that was yielded by the generator, while the done
property is a boolean that indicates whether the generator has finished executing.
In the example above, we call the next()
method three times and print the result to the console. Each call to next()
causes the generator to resume execution from where it left off and generate the next value in the sequence.
Generators can also receive input from the caller using the yield
keyword. When the caller calls the generator’s next()
method, it can pass a value as an argument, which becomes the result of the yield
expression inside the generator.
Here’s an example:
function* echoGenerator() {
const message = yield;
console.log(`You said: ${message}`);
}
const generator = echoGenerator();
generator.next(); // start the generator
generator.next("Hello, world!"); // pass input to the generator
In this example, we define a generator function called echoGenerator
that expects to receive input from the caller. When the generator starts executing, it enters a paused state waiting for input. The yield
keyword without an expression produces a undefined
value and pauses the execution of the generator.
We then create a new Generator object based on the echoGenerator
function and assign it to the variable generator
. We call the generator’s next()
method to start it, which causes it to pause at the yield
expression.
We then call the next()
method again, passing the string 'Hello, world!'
as an argument. This causes the generator to resume execution from where it left off and assign the value of 'Hello, world!'
to the message
variable. It then logs the message "You said: Hello, world!"
to the console.
Usage of Generator function to generate a sequence of Fibonacci numbers:
function* fibonacciGenerator() {
let [prev, curr] = [0, 1];
while (true) {
yield curr;
[prev, curr] = [curr, prev + curr];
}
}
const generator = fibonacciGenerator();
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: 3, done: false }
This generator function uses destructuring assignment to initialize two variables, prev
and curr
, to 0 and 1, respectively. It then enters an infinite loop, yielding the value of curr
in each iteration and updating prev
and curr
to be the next pair of Fibonacci numbers.
When you create a new Generator object based on this function, it starts executing immediately. You can then call its next()
method to generate the next value in the sequence. In the example above, we call the next()
method four times and print the result to the console.
Generators can also be used to iterate over collections like arrays or objects. You can use the yield*
keyword to delegate to another Generator object or an iterable object such as an array or a string.
Usage of Generator function to iterate over elements of array:
Here’s an example of a Generator function that iterates over an array of numbers:
function* numberIterator(numbers) {
for (let i = 0; i < numbers.length; i++) {
yield numbers[i];
}
}
const generator = numberIterator([1, 2, 3, 4]);
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: 3, done: false }
console.log(generator.next()); // { value: 4, done: false }
This generator function takes an array of numbers as an argument and iterates over it using a for
loop. In each iteration, it yields the current number. We then create a new Generator object based on this function and pass it an array of numbers. We call its next()
method four times to generate the next number in the sequence.
Thank you for reading, and let’s have conversation with each other
Thank you for reading my article. Let’s have conversation on Twitter and LinkedIn by connecting.