Before understanding generators, we need to take a look on iterables.
Iterables
Iterables are objects which can be iterated. Like array,set etc. So if you log an array and check it's prototype, you will find one property Symbol.iterator
which is a function that can be used to make an array iterable.
So after execution of following code you can check an iterator and how to get values through it :
let numArray = [1,2,3,4];
console.dir(numArray);
const numIterable = numArray[Symbol.iterator]();
console.log(numIterable.next());
console.log(numIterable.next());
console.log(numIterable.next());
console.log(numIterable.next());
console.log(numIterable.next());
and you will see following output :
next
function return one object, which has two keys : value
and done
. After last item in iterable, value will be undefined and done becomes true.
Generators :
Generator are basically functions which can return more than one values, represented by function* <name>
or function *<name>
. By calling generator, it doesn't return values instead returns a generator object. To get values, you have to call it's next()
method, which will return an object having structure
{value: <value>, done: true/false}
. Please check below example which returns multiple of 5.
In above example, you can see that by calling generateMultipleFive
function, it is returning an object, then we can call next() method on that object. It will return an object having value and done as keys.
So the question comes, it is only first value, how we can get all values ? Answer is, you have to run next
method every time to get next values. done
property will return false in every case.
Also, after returning last value, if you will run next method again, it will return done as true. If we use return
instead of yield
for returning last value, then done
will be true
for that case . Please run below code in console to check this behavior :
Relation between Generators and iterable
Since genrators have next method and calling next gives object containing value and done as keys, so basically generators are iterable. You can use for...of loop to get all values. See below example
Nesting In Generators
A generator can be used inside another generator called Generator Composition. Special syntax yield* <function name>
is used for achieving this. In below example, I have used composition of generators to print tables of three numbers. Outer generator calls inner generator through yield*
syntax, which yields numbers in table.
How generators are different from iterables
Till now, you can say that iterables also can do stuff which generator can do, then how generator is different ? Answer is, Combination of yield and next() can be used to not only returning the result, but also passing the value inside the generator.To do so, we should call generator.next(arg), with an argument. That argument becomes the result of yield. Check below example for this :
Execution stops at line yield "2 + 2 = ?"
and when statement generator.next().value
is called, it assign question string to variable question. And statement generator.next(4);
assign result to result variable, where execution was paused in generator function.
So this was a basic understanding of Generators.
Top comments (0)