JavaScript Yield Keyword

JavaScript Yield Keyword

In this article, I am going to discuss JavaScript yield Keyword with Examples. Please read our previous article where we discussed JavaScript Function Generator in detail.

JavaScript yield Keyword

yield keyword is used to start or stop a generator function asynchronously. A generator function is same as like a normal function but the difference is that whenever the function is returning any value, it returns it with the help of ‘yield’ keyword instead of return it.

The yield keyword makes the call to the generator’s next() method to return an IteratorResult object with two properties: value and done. “value” property which is the actual value of evaluating the yield expression and “done” which is a Boolean value, it returns true when generator function is full completed else it returns false, indicating that the generator function has not fully completed.

If we pause the yield expression, the generator function will also get paused and resumes only when we call the next() method. When the next() method is encountered the function keeps on working until it faces another yield or returns expression or any exception is thrown by the generator function.

yield can only directly call from the generator function that contains it. Yield can’t be called from nested functions or from callbacks.

Syntax: yield[expression]

Example-1 JavaScript yield:
<html>
<head>
    <title>JavaScript yield example-1. </title>
</head>
<body>
    <h3>JavaScript yield example-1 Web Page</h3>
    <script>
        function* showValues(i) {
            while (i < 3) {
                yield i++;
            }
        }

        //creating an object for our function showValues
        const showVal = showValues(0);

        //return 0 because 0 value is passed to the showValues yield expression
        console.log(showVal.next().value);

        // return 1
        console.log(showVal.next().value);

        //return 2
        console.log(showVal.next().value);
    </script>
</body>
</html>

Output:

Example-1 JavaScript yield

Example-2:
<html>
<head>
    <title>JavaScript yield example-2 </title>
</head>
<body>
    <h3>JavaScript yield example-2 example Web Page</h3>
    <script>
        function* countSales() {
            let saleList = [3, 7, 5]
            for (let i = 0; i < saleList.length; i++) {
                yield saleList[i]
            }
        }

        let salesStore = countSales()  // Generator { }
        console.log(salesStore.next())      // { value: 3, done: false }
        console.log(salesStore.next())      // { value: 7, done: false }
        console.log(salesStore.next())      // { value: 5, done: false }
        console.log(salesStore.next())      // { value: undefined, done: true }
    </script>
</body>
</html>

Output:

JavaScript Yield Keyword

Example-3:
<html>
<head>
    <title>JavaScript yield example-3.</title>
</head>
<body>
    <h3>JavaScript yield example-3 Web Page</h3>
    <script>
        function* incompleteYield() {

            /*expression paused here and return
            value is undefined as nothing is declared*/
            yield;

            //wait for next() to finish
            msg(yield "Welcome to GFG");
        }

        function msg(x) {
            console.log("Hello World ", x)
        }

        var generator = incompleteYield();

        //return undefined
        console.log(generator.next());

        //return Welcome to GFG
        console.log(generator.next());

        /*if we stop here, it will be done remains false as we have not called next
        so that "Hello World" is still left there to process*/

        //return undefined with done as true as the calling generatior funnction is full completed
        console.log(generator.next());
    </script>
</body>
</html>

Output:

JavaScript Yield Keyword with Examples

JavaScript yield* keyword

The yield* expression is used to delegate to another Generator or iterable object.

yield V/S yield*

Yield yield*
Pauses the generator execution and it returns the value of the expression which is being written after the yield keyword. It iterates over the operand and returns each value until done is true
Built-in iterables

String, Array, TypedArray, Map and Set are all built-in iterables, because their prototype objects all have a Symbol.iterator method.

Syntax: yield * expression; Here the expression which returns an iterable objects

The yield* expression iterates over the operand and yields each value returned by it. The value of yield* expression itself is the value returned by that iterator when it’s closed (i.e., when done is true).

Example JavaScript yield*:
<html>
<head>
    <title>JavaScript yield* example.</title>
</head>
<body>
    <h3>JavaScript yield* example Web Page</h3>
    <script>
        function* func1() {
            yield 52;
        }

        function* func2() {
            yield* func1();
        }

        const iterator = func2();

        console.log(iterator.next().value);
        // expected output: 52
    </script>
</body>
</html>

Output: 52

Delegating to another Generator

From within a generator function, the control can be delegated/assigned to another generator function using yield*.

In the following code, values yielded by generator1() are returned from next() calls just like those which are yielded by generator2(). This way we can chain/add as many generators as we want.

Example: Delegating to another Generator
<html>
<head>
    <title>JavaScript yield* Delegating to another generator example. </title>
</head>
<body>
    <h3>JavaScript yield* delegating to another generator example Web Page</h3>
    <script>
        function* generator1() {
            yield 2;
            yield 3;
            yield 4;
        }

        function* generator2() {
            yield 1;
            yield* generator1();
            yield 5;
        }

        const iterator = generator2();

        console.log(iterator.next()); // {value: 1, done: false}
        console.log(iterator.next()); // {value: 2, done: false}
        console.log(iterator.next()); // {value: 3, done: false}
        console.log(iterator.next()); // {value: 4, done: false}
        console.log(iterator.next()); // {value: 5, done: false}
        console.log(iterator.next()); // {value: undefined, done: true}
    </script>
</body>
</html>

Output:

Delegating to another Generator

Yield Other Iterable objects

Besides generator objects, yield* can also yield other kinds of iterables such as arrays, strings, or argument objects.

Example: Yield Other Iterable objects
<html>
<head>
    <title>JavaScript yield* other iterable objects example. </title>
</head>
<body>
    <h3>JavaScript yield* other iterable objects example Web Page</h3>
    <script>
        function* generator3() {
            yield* [1, 2];
            yield* '40';
            yield* Array.from(arguments);
        }

        const iterator = generator3(5, 6);

        console.log(iterator.next()); // {value: 1, done: false}
        console.log(iterator.next()); // {value: 2, done: false}
        console.log(iterator.next()); // {value: "4", done: false}
        console.log(iterator.next()); // {value: "0", done: false}
        console.log(iterator.next()); // {value: 5, done: false}
        console.log(iterator.next()); // {value: 6, done: false}
        console.log(iterator.next()); // {value: undefined, done: true}
    </script>
</body>
</html>

Output:

Yield Other Iterable objects

The value of yield* expression itself

As we have learned in our previous topics that yield* is an expression, not a statement. Hence, it evaluates the value.

Example: value of yield* expression itself
<html>
<head>
    <title>JavaScript yield* expression example. </title>
</head>
<body>
    <h3>JavaScript yield* expression example Web Page</h3>
    <script>
        function* gen4() {
            yield* [1, 2, 3];
            return 'John Doe';
        }

        function* gen5() {
            const g4ReturnValue = yield* gen4();
            console.log(g4ReturnValue) // 'John Doe'
            return g4ReturnValue;
        }

        const iterator = gen5();

        console.log(iterator.next()); // {value: 1, done: false}
        console.log(iterator.next()); // {value: 2, done: false}
        console.log(iterator.next()); // {value: 3, done: false} done is false because gen5 generator isn't finished, only g4
        console.log(iterator.next()); // {value: ' John Doe', done: true}
    </script>
</body>
</html>

Output:

value of yield* expression itself

In the next article, I am going to explain Iterators and Iterables in JavaScript with examples. Here, in this article, I try to explain JavaScript yield Keyword with examples. I hope this JavaScript Yield keyword article will helps you with your need. I would like to have your feedback. Please post your feedback, question, or comments about this article.

Leave a Reply

Your email address will not be published. Required fields are marked *