Generators in JavaScript are the functions that can be paused and resumed.
1function* genFunc(){...}
Calling genFunc() doesn't execute the body of the function.
1const genObj = genFunc();
Instead, it returns generator object which can be used to control the execution of the generator.
genObj.next() will start executing the function and it will execute till it reaches yield keyword.
We can think of yield as return for now. It is similar to C# yield.
1function* genFunc() { 2 console.log("First"); 3 yield; 4 console.log("Second"); 5} 6const genObj = genFunc(); 7genObj.next(); 8 9/* 10output 11 12First 13*/
Calling genObj.next() again will resume the further execution after yield.
1function* genFunc() { 2 console.log("First"); 3 yield; 4 console.log("Second"); 5} 6const genObj = genFunc(); 7genObj.next(); 8genObj.next(); 9 10/* 11output 12 13First 14Second 15*/
Here's how the execution looks like:
yield is not allowed inside non-generator functions. That is, yielding in callbacks doesn't work.
We can also pass the data to generator function via next.
1function* genFunc() { 2 console.log("First"); 3 const input = yield; 4 console.log(input); 5 console.log("Second"); 6} 7const genObj = genFunc(); 8genObj.next(); 9genObj.next("Third"); 10 11/* 12output 13 14First 15Third 16Second 17*/
We can retrieve the yielded values via the generator object genObj:
1function* genFunc() { 2 console.log("First"); 3 const input = yield; 4 console.log(input); 5 console.log("Second"); 6 yield "Forth"; 7} 8const genObj = genFunc(); 9genObj.next(); 10const result = genObj.next("Third"); 11console.log(result); 12 13/* 14output 15 16First 17Third 18Second 19{ 20 done: false, 21 value: "Forth" 22} 23*/
We can have multiple yield in the function as shown in the above example.
Once, the execution of the generator function is completed, further calls to genObj.next() will have no effect.
Further reading
We highly recommend Exploring ES6 by Dr. Axel Rauschmayer to go deeper on this topic.