如何在 JavaScript 类中编写生成器?

新手上路,请多包涵

通常,我写这样的代码:

 //definition
exports.getReply = function * (msg){
    //...
    return reply;
}
//usage
var msg = yield getReply ('hello');

但是我如何在 es6 类中编写和使用生成器呢?我试过这个:

 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`?

我也试过:

  class Reply{
      getReply(){
         return function*(msg){
            //...
            return reply;
         }
      }
    }

所有这两种方法似乎都是错误的答案。那么如何在类中正确编写生成器函数呢?

原文由 Seven 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 451
2 个回答

编辑:添加更多示例。

您的 class 定义(几乎)正确。错误出现在实例化中 var Reply = new Reply(); 。这会尝试重新定义分配给类名的变量。另外 generator 功能预计 yield 一些东西。我详细阐述了一些 OP 代码来展示工作示例。

 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);
}

2019 年 1 月 12 日更新

正如@BugBuddy for..of 所建议的那样,循环看起来更好(但并非在所有情况下都有效)。查看代码段中的更新行。

原文由 Alex Kudryashev 发布,翻译遵循 CC BY-SA 4.0 许可协议

TL;对来自谷歌的困惑访问者的 DR:

在 Javascript 中,如何在类中编写生成器函数?

 class A {
    * values() {
        yield "a value";
        yield* [1, 2, 3, 4, 5];
    }
}

在语法上是正确的。有用。不客气,现在被解雇了。

原文由 Константин Ван 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题