Generator Functions in JavaScript
Before I start writing anything, here's a discloser: I knew about generator functions since a long time, but did not really had a chance to use them. In this blogpost, I will demonstrate implementation of generator functions in real-world scenerios.
Generator Function
Before we begin, let's quickly revise what generator functions are. They are a special kind of function which is used to generate an iterator.
An Iterator is an Object which implements the Iterator Protocol.
The Iterator Protocol defines a standard way to produce sequential values and potentially a return value when all values have been generated. - MDN
Function Signature for Generator Functions
Function signature for a Generator Function is similar to a regular function.
The only difference is that, in iterator function, keyword function
is
followed by an astrics(*
).
// function signature
function* generator(args) {}
yield
Keyword
As soon as the keyword yield
is encountered, the function execution will
pause. And the value will be returned.
// generator function
function* myGen() {
yield 1;
yield 2;
}
Iterator.next(arg)
Method
next()
is a method to return the current state of the generator function.
next()
returns an object containing keys value
and done
. value
holds
whatever is returned by yield
. And done
shows if the complete function is
done executing.
function* myGen() {
yield 1;
yield 2;
}
const it = myGen();
myGen.next(); // { value: 1, done: false }
myGen.next(); // { value: 2, done: false }
Interesting thing is that, next()
may accpet a value if passed. Passed value
will be returned as yield
expression. For example, name = yield name
.
Whatever is passed to next()
method, will be stored in variable name
.
Arguments passed to first invocation of
next()
will be ignored.
Iterator.return()
Method
Assume that, for some reason, you need to complete executing the whole generator
function immediately. In such cases, do we have a viable option? Yes! it's
called return()
Examples
Just as the title says, I am going to provide a few useful real-world usecases for generator functions.
1. Generating Unique ID
Unique IDs are important at multiple scenerios. It gets tricky to generate those. Most of the time we depend upon external libraries.
To generate an unique ID, either we could simply write a number generator using Generator Functions. Or we could convert them to some sort of strings. Both ways works good.
Below is an example to generate unique strings.
function* GenerateUniqueID() {
let i = 0;
while (true) {
const str = btoa(i);
i++;
yield str;
}
}
What this would do? It will simply create a Base64 representation of a given number. Use this output as classname/key/id for any HTML element.
Another method could be to hash that number using MD5, SHA or similar. This way, the resultant string would always be equal in length.
#wip