Back to: JavaScript Tutorial For Beginners and Professionals
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-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:
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
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:
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:
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:
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.
About the Author: Pranaya Rout
Pranaya Rout has published more than 3,000 articles in his 11-year career. Pranaya Rout has very good experience with Microsoft Technologies, Including C#, VB, ASP.NET MVC, ASP.NET Web API, EF, EF Core, ADO.NET, LINQ, SQL Server, MYSQL, Oracle, ASP.NET Core, Cloud Computing, Microservices, Design Patterns and still learning new technologies.