Usually, I write code like this:
//definition exports.getReply = function * (msg){ //... return reply; } //usage var msg = yield getReply ('hello');
but how can I write and use a generator in and out of an es6 class? I tried this:
class Reply{ *getReply (msg){ //... return reply; } *otherFun(){ this.getReply(); //`this` seem to have no access to `getReply` } } var Reply = new Reply(); Reply.getReply(); //out of class,how can I get access to `getReply`?
I also tried:
class Reply{ getReply(){ return function*(msg){ //... return reply; } } }
All of these two methods seem to be wrong answers. So how can I write generator functions in a class correctly?
In ECMAScript 2015, generators were introduced to the JavaScript language. A generator is a process that can be paused and resumed and can yield multiple values. A generator in JavaScript consists of a generator function, which returns an iterable Generator object.
In JavaScript, a generator is a function which returns an object on which you can call next() . Every invocation of next() will return an object of shape — { value: Any, done: true|false. }
The function* declaration ( function keyword followed by an asterisk) defines a generator function, which returns a Generator object.
JavaScript generators are just ways to make iterators. They use the yield keyword to yield execution control back to the calling function and can then resume execution once the next() function is called again.
Edit: Add more examples.
Your class
definition is (almost) correct.The error was in instantiation var Reply = new Reply();
. This tries to redefine variable assigned to class name. Also generator
function is expected to yield
something. I elaborated a little OP code to show working example.
class Reply { //added for test purpose constructor(...args) { this.args = args; } * getReply(msg) { for (let arg in this.args) { let reply = msg + this.args[arg]; //generator should yield something yield reply; } //next call returns (yields) {done:true,value:undefined} } * otherFun() { yield this.getReply('Nice to meet you '); //yields Generator object yield this.getReply('See you '); //Yes, this can access //next call yields {done:true, value:undefined} } * evenMore() { yield* this.getReply('I miss you '); //yields generator result(s) yield* this.getReply('I miss you even more '); } } //now test what we have const reply = new Reply('Peter', 'James', 'John'); //let and var here are interchangeable because of Global scope var r = reply.getReply('Hello '); var msg = r.next(); //{done:false,value:"..."} while (!msg.done) { console.log(msg.value); msg = r.next(); } var other = reply.otherFun(); var o = other.next(); //{done:false,value:Generator} while (!o.done) { let gen = o.value; msg = gen.next(); while (!msg.done) { console.log(msg.value); msg = gen.next(); } o = other.next(); } var more = reply.evenMore(); msg = more.next(); while (!msg.done) { console.log(msg.value); msg = more.next(); } //update of 1/12/2019 //more examples for (let r of reply.getReply('for ')) { console.log(r); } for (let r of reply.evenMore()) { console.log(r); } //note that the following doesn't work because of lack of star (*) inside the generator function for (let r of reply.otherFun()) { console.log(r); }
UPDATE 1/12/2019
As suggested by @BugBuddy for..of
loop looks even nicer (But doesn't work in all cases). See updated lines in the snippet.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With