How to use the Generator function* in JavaScript

Yadav, Niteesh
Mar 12 · 4 min read

Function keyword followed by an asterisk is used to define a generator function, which returns a Generator object.

We can exit and re-entered the generator function later on. In case of re-entrances, their context (variable bindings) will be saved.

Important point to note here is that calling a generator function does not execute its body immediately, in fact it returns an iterator object for the function.

In short, a generator appears to be a function but it behaves like an iterator.

Syntax :

function* generatorFunctionName([param[, param[, ... param]]]) {
statements
}
  • name : Function name
function* generator(i) {
yield i;
yield i + 1;
}
const gen = generator(1);
console.log(gen.next().value);
// expected output: 1
console.log(gen.next().value);
// expected output: 2

Generate body will get executed only when the iterator’s next() method is called. Execution take place until the first yield expression, which specifies the value to be returned from the iterator or, with yield*, delegates to another generator function.

The next() method returns an object with a value property containing the yielded value and a done property which indicates whether the generator has yielded its last value, as a Boolean.

{ 
value: AnyValue,
done: true|false
}

To resume the generator function execution, we can call the next() method with an argument. This action will also results in replacing the yield expression where execution was paused with the argument from next().

To finish the execution of the generator function, we can use the return statement. Returned value will be used to set the value property of the object returned by the generator. Any exception thrown inside the generator function, will also result in making the generator finish, unless it has been caught inside it’s body.

GeneratorFunction constructor, or the function expression syntax can also be used to define Generator functions. However, we should keep in mind that Generators are not constructable.

function* generatorFunction() {}
var obj = new generatorFunction;
// Uncaught TypeError: generatorFunction is not a constructor

Once generator is finished, we will not be able to execute any of the generator’s code using subsequent next() calls. They will just return an object of this form: {value: undefined, done: true}. In below example, we can check the same.

function* generatorFunction() {
var index = 0;
while (true)
{
yield index++;
if(index > 2)
{
return;
}
}
}
var gen = generatorFunction();console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
// Output -->
{ value: 0, done: false }
{ value: 1, done: false }
{ value: 2, done: false }
{ value: undefined, done: true }

Passing arguments into Generators :

function* logGenerator(i) {
while(i < 3)
{
console.log(i++, yield);
}
}
var gen = logGenerator(0);// the first call of next executes from the start of the function
// until the first yield statement
gen.next();
gen.next('Logging Starts...');
gen.next('Logging Going On...');
gen.next('Logging Ends...');
// Output -->
0 Logging Starts...
1 Logging Going On...
2 Logging Ends...

Using yield* :

function* anotherGenerator(i) {
yield i + 10;
yield i + 20;
yield i + 30;
}
function* functionGenerator(i) {
yield i;
yield* anotherGenerator(i);
yield i + 1;
}
var gen = functionGenerator(1);console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
// Output -->
{ value: 1, done: false }
{ value: 11, done: false }
{ value: 21, done: false }
{ value: 31, done: false }
{ value: 2, done: false }

NOTE : We can also use Generator functions in asynchronous programming in conjugation with Promises as using them will mitigate — if not entirely eliminate — the problems with callbacks, such as Callback Hell and Inversion of Control. However, we an also do the same using async function, whose implementation will be much simpler.

Browser Compatibility

Conclusion

  • Generators are a special class of functions that simplify the task of writing iterators.

That’s it for now. In below article, I have covered more about Generator functions like Use cases, advantages and so on…

How to use the Generator function* in JavaScript (continued…)


References

Mozilla MDN
Codeburst


A note from JavaScript In Plain English:

We are always interested in helping to promote quality content. If you have an article that you would like to submit to JavaScript In Plain English, send us an email at submissions@javascriptinplainenglish.com with your Medium username and we will get you added as a writer.

JavaScript In Plain English

New articles every day.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store