Generator functions
In JavaScript, generator functions are special functions whose execution can be paused and continued later. In simple words, we can stop the execution of a generator function temporarily, and then start it from the same point later on.
Let’s first see how a normal function works.
function normalFunction() {
console.log("Executing a normal function");
console.log("Execution cannot be stopped");
}
normalFunction();
Following is the output of the above code.
The function is executed in a normal way, i.e. top to bottom and ends when the function body ends.
Now, observe the following function
function* generatorFunction() {
console.log("Execution starts...");
yield 1;
console.log("Execution is midway...");
yield 2;
console.log("Execution ends...");
}
This is not a regular function, instead, it is a generator function because it is created using an asterisk (*) symbol. Moreover, inside the body, the “yield” keyword is used. Let’s understand the need for an asterisk symbol and “yield” keyword.
The asterisk symbol is used to define a generator function while the “yield” keywords pause the execution. So in simple terms, a function defined with an asterisk symbol is a generator function and whenever a yield statement is encountered in it, the execution pauses.
A generator function is not called like a regular function. To call it, first, we have to create a generator object. Observe the following code.
function* generatorFunction() {
console.log("Execution starts...");
yield 1;
console.log("Execution is midway...");
yield 2;
console.log("Execution ends...");
}
const generator = generatorFunction()
console.log(generator)
“generatorFunction()” is stored in a variable. Let’s see what is the value of “generator”.
The value of “generator” is a Generator object, meaning, the generator function returns an object.
Now, this object would be used to call the generator function. To call it, we need the in-built “next” method.
function* generatorFunction() {
console.log("Execution starts...");
yield 1;
console.log("Execution is midway...");
yield 2;
console.log("Execution ends...");
}
const generator = generatorFunction()
generator.next()
Observe the output.
If you observe carefully, only that console statement is executed which is placed before the first yield. But why? This happens because the execution stops when the yield statement is executed.
The “next” method returns an object. Let’s store the “next” methods in an object and check what is the returning value.
function* generatorFunction() {
console.log("Execution starts...");
yield 1;
console.log("Execution is midway...");
yield 2;
console.log("Execution ends...");
}
const generator = generatorFunction()
const next1 = generator.next()
console.log(next1)
Observe the output.
The returning object has two fields - “done” and “value”. The value of “value” is 1, which is also the value written alongside the first “yield”.
yield 1;
So, the “value” denotes the value of the “yield” while “done” whose value is “false”, denotes that function has not been executed completely.
If we use the “next” method once again, the execution will start from where it stopped and will continue until the next “yield” is encountered.
So, we have three “next” methods in the code. First, the “yield” with “value” 1 is returned. Then the execution starts after that “yield” and runs until the “yield” with “value” 2 is encountered. When the last “next” method is executed, the value of “done” changes to “true” because there is no more “yield” statement, meaning, the function cannot be paused anymore. Moreover, the “value” is also “undefined”.
Wrapping it up
The Generator function is a powerful feature introduced in ES6. Such types of functions are used heavily in modern JavaScript development. One of the major uses of the generator function is to handle asynchronous calls. There are several other uses.
No comments :
Post a Comment