in , ,

JavaScript Generators

JavaScript Generators
JavaScript Generators

In this tutorial, you will learn about JavaScript generators with the assistance of examples.

Introduction

In ECMAScript 2015, generators were introduced with the JavaScript language. A generator is a process that can be stopped and continued and can yield various values. A generator in JavaScript comprises a generator function, which restores an iterable Generator object.

Generators can look after state, giving an effective method to make iterators, and are equipped for managing limitless information streams, which can be used to actualize infinite look on the frontend of a web application, to work on sound wave information, and more. Also, when used with Promises, generators can imitate the async/await usefulness, which allows us to manage nonconcurrent code in a more direct and comprehensible way. Although async/await is a more predominant approach to manage normal, straightforward asynchronous use cases, such as getting information from an API, generators have further developed highlights that make learning out how to use them worthwhile

In JavaScript, generators furnish another approach to work with functions and iterators.

Using a generator,

• you can stop the execution of a function from anyplace inside the function

• and keep executing code from a stopped position


Create JavaScript Generators

To make a generator, you need to initially characterize a generator work with function* symbol. The objects of generator functions are called generators.

// define a generator function
function* generator_function() {
   ... .. ...
}

// creating a generator
const generator_obj = generator_function();

Note: The generator work is meant by . You can either use function generatorFunc() {…} or function *generatorFunc(){…} to create them.


Using yield Pause Execution

As referenced above, you can stop the execution of a generator work without executing the entire function body. For that, we use the yield keyword. For instance,

// generator function
function* generatorFunc() {

    console.log("1. code before the first yield");
    yield 100;
    
   console.log("2. code before the second yield");
    yield 200;
}

// returns generator object
const generator = generatorFunc();

console.log(generator.next());

Output

1. code before the first yield
{value: 100, done: false}

Here,

  • A generator object named generator is made.
  • When generator.next() is called, the code up to the main yield is executed. At the point when the yield is encountered, the program returns the worth and stops the generator work.

Note: You need to assign generator objects to a variable before you use it.


Working of different yield Statements

The yield articulation returns a worth. Nonetheless, in contrast to the return articulation, it doesn’t end the program. That is the reason you can keep executing code from the last yielded position. For instance,

function* generatorFunc() {

    console.log("1. code before first yield");
    yield 100;

   console.log("2. code before the second yield");
    yield 200;

    console.log("3. code after the second yield");
}

const generator = generatorFunc();

console.log(generator.next());
console.log(generator.next());
console.log(generator.next());

Output

1. code before first yield
{value: 100, done: false}
2. code before second yield
{value: 200, done: false}
{value: undefined, done: true}

Here is the manner by which this program works.

The first generator.next() explanation executes the code up to the main yield proclamation and stops the execution of the program.

The second generator.next() begins the program from the stopped position.

At the point when all the components are accessed to, it returns {value: undefined, done: true}.


Passing Arguments to Generator Functions

You can likewise pass contentions to a generator work. For instance,

// generator function
function* generatorFunc() {

    // returns 'hello' at first next()
    let x = yield 'hello';
    
    // returns passed argument on the second next()
    console.log(x);
    console.log('some code');

    // returns 5 on second next()
    yield 5;
    
}

const generator = generatorFunc();

console.log(generator.next());
console.log(generator.next(6));
console.log(generator.next());

Output

{value: "hello", done: false}
6
some code
{value: 5, done: false}
{value: undefined, done: true}

In the above program,

  • The first generator.next() returns the value of the yield (in this case, ‘hello’). However, the value is not assigned to variable x in let x = yield ‘hello’;
{value: "hello", done: false}
  • When generator.next(6) is encountered, the code again begins at let x = yield ‘hello’; and the contention 6 is assigned to x. Additionally, the remaining code is executed up to the subsequent yield.
6
some code
{value: 5, done: false}
  • At the point when the third next() is executed, the program returns {value: undefined, done: true}. It is on the grounds that there are no other yield statements.
{value: undefined, done: true}

Generators are Used for Implementing Iterables

Generators give a simpler method to implement iterators.

In the event that you need to actualize an iterator manually, you need to make an iterator with the next() strategy and save the state. For instance,

// creating iterable object
const iterableObj = {

    // iterator method
    [Symbol.iterator]() {
        let step = 0;
        return {
            next() {
                step++;
                if (step === 1) {
                    return { value: '1', done: false};
                 }
                else if (step === 2) {
                    return { value: '2', done: false};
                }
                else if (step === 3) {
                    return { value: '3', done: false};
                }
                return { value: '', done: true };
            }
        }
    }
}

for (const i of iterableObj) {
 console.log(i);
}

Output

1
2
3

Since generators are iterables, you can execute an iterator in a simpler manner. At that point, you can iterate through the generators using the for…of loop. For instance,

// generator function
function* generatorFunc() {
  
    yield 1;
    yield 2;
    yield 3;
}

const obj = generatorFunc();

// iteration through generator
for (let value of obj) {
    console.log(value);
}

Generator Methods

MethodDescription
next()Returns a value of yield
return()Returns a value and terminates the generator
throw()Throws an error and terminates the generator

JavaScript return Vs yield Keyword

return Keywordyield Keyword
Returns the worth and ends the function.Returns the worth and stops the function, however, doesn’t end the function.
Accessible in both the typical functions and generator functions.Accessible just in generator functions.

JavaScript Generator Function With the return

You can use the return statement in a generator work. The return statement returns a worth and ends the function (like normal functions). For instance,

// generator function
function* generatorFunc() {

    yield 100;

   return 123;

   console.log("2. some code before second yield");
    yield 200;
}

// returns generator object
const generator = generatorFunc();

console.log(generator.next());
console.log(generator.next());
console.log(generator.next());

Output

{value: 100, done: false}
{value: 123, done: true}
{value: undefined, done: true}

In the above program, when the return statement is encountered, it returns the worth and done property turns out to be valid, and the function ends. Consequently, the next() technique after the return statement doesn’t return anything.

Note: You can likewise use the return() technique rather than the return statement like the generator.return(123); in the above code.


JavaScript Generator Throw Method

You can expressly throw a mistake on the generator work using the throw() method. The use of throw() strategy throws a blunder and ends the function. For instance,

// generator function
function* generatorFunc() {
    yield 100;
    yield 200;
}

// returns generator object
const generator = generatorFunc();

console.log(generator.next());

// throws an error
// terminates the generator
console.log(generator.throw(new Error('Error occurred.')));
console.log(generator.next());

Output

{value: 1, done: false}
Error: Error occurred.

Uses of Generators

  • Generators let us compose cleaner code while composing asynchronous assignments.
  • Generators give a simpler method to execute iterators.
  • Generators execute their code just when required.
  • Generators are memory proficient.

Generators were introduced in ES6. Some browsers may not support the use of generators. To learn more, visit JavaScript Generators support.


Thanks for reading! We hope you found this tutorial helpful and we would love to hear your feedback in the Comments section below. And show us what you’ve learned by sharing your photos and creative projects with us.

salman khan

Written by worldofitech

Leave a Reply

JavaScript Iterators and Iterables

JavaScript Iterators and Iterables

JavaScript Regex

JavaScript Regex