Usually, I write code like this:
//definition
exports.getReply = function * (msg){
//...
return reply;
}
//usage
var msg = yield getReply (\'hello\'
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.
Generators are functions with a .next()
for getting the yield
'ed values or you can yield
a generator function to let it know it doesn't need to "wait" upon encountering a yield
statement for a .next
to be called (reply.getReply().next(fn)
)
Your second piece of code is almost correct:
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`?
First of all, please use const
or let
when working in ES6 and only use the uppercase variant for classes.
You are trying to overwrite the class Reply
statement with the var Reply =
statement, which is not possible since the Identifier 'Reply'
is already declared.
The answer you are looking for is as followed:
Just like you are doing in the first example, you should yield
the generator functions, so your could should look like this:
class Reply{
*getReply (msg){
// yield something here, otherwise you should use a normal function
return reply;
}
*otherFun(){
const reply = yield this.getReply(); // yield the generator so it does what it needs to and doesn't wait for the .next() to be called on it
return `${reply} within class ${this.constructor.name}`;
}
}
const reply = new Reply();
const answer = yield reply.getReply('foo');
// getReply is a generator function, so it needs a `yield` or `.next()` to run beyond the first `yield` in the function
In Javascript, how do I write a generator function in a class?
class A {
* values() {
yield "a value";
yield* [1, 2, 3, 4, 5];
}
}
is syntactically correct. It works. You’re welcome and now dismissed.