A simple generator example:
function* somewords() { yield "hello"; yield "world"; } for (var word of somewords()) { alert(word); }
yield method is executed once for each call to the.next() method
How to turn off the generator:
Let's first learn about the characteristics of the generator
generator.return() generator.next()Optional parameters generator.throw(error) yield*
Previous methods:
function dothings() { setup(); try { // ...do something } finally { cleanup(); } } dothings();
Cleaup() can be used to close connections or files, release resources, update dom s, and so on.
Generator Version:
function* producevalues() { setup(); try { // ...generate some values } finally { cleanup(); } } for (var value of producevalues()) { work(value); }
ES6 will do the cleanup for us automatically. As mentioned earlier, the iterator iterator interface only supports the optional. return() method, and when {done:true} is returned it exits the auto-call method
Generator Lead Mode
Generators can be used to implement asynchronous programming to do everything you do with asynchronous callbacks or promise chains. The generator's.next() method accepts an optional parameter that will later appear in the generator as a return value of the yield expression.That is, unlike the return statement, the yield statement is an expression that has a value only when the generator is restored.
var results = yield getdataandlatte(request.areacode)
This process returns useful information and pauses the generator at any time until someone calls.Next ({data:., coffee:...}), stores the obtained variable in results, and executes the next line of code:
function* handle(request) { var results = yield getdataandlatte(request.areacode); results.coffee.drink(); var target = mosturgentrecord(results.data); yield updatestatus(target.id, "ready"); }
yield still retains its original meaning: pause generator, return value to caller
Ordinary functions are different and tend to be more responsive to the needs of the caller.Extensible Generator:
function rungeneratoronce(g, result) { var status = g.next(result); if (status.done) { return; // phew! } // Generator asks us to get something and // Call it back when we're done doasynchronousworkincludingespressomachineoperations( status.value, (error, nextresult) => rungeneratoronce(g, nextresult)); }
You also need to create a generator and run it once:
rungeneratoronce(handle(request), undefined);
Generators generally generate Promise objects to tell the caller what to do
How to destroy the generator
Generator error handling: If an error occurs, instead of executing.next(), it executes.throw(error); exceptions thrown inside the generator always propagate to the caller.So generator.throw(error) throws an error and returns it to you immediately, whether or not the generator captures an error.
When the generator executes a yield expression and pauses, the following functions can be achieved:
- Call generator.next(value), and the generator resumes execution from where it left off.
- generator.return() is called, passing an optional value, and the generator executes only the final block of code and does not resume execution.
- Call generator.throw(error), which behaves like a yield expression calling a function and throwing an error.
- Or do nothing and the generator will always freeze
Combining generators for more functionality
Write a simple generator function to join two iterative objects
function* concat(iter1, iter2) { for (var value of iter1) { yield value; } for (var value of iter2) { yield value; }} //ES6 function* concat(iter1, iter2) { yield* iter1; yield* iter2; }
A normal yield expression produces only one value, whereas a yield* expression can iterate through an iterator to generate all values.
Generators can be invoked using yield*using a generator:
function* factoredoutchunkofcode() { ... } function* refactoredfunction() { ... yield* factoredoutchunkofcode(); ... }
This section refers to ES6-In-Depth