如何在JavaScript类中编写生成器? [英] How can I write a generator in a JavaScript class?

查看:60
本文介绍了如何在JavaScript类中编写生成器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常,我写这样的代码:

Usually, I write code like this:

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

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

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

我也尝试过:

 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?

推荐答案

添加更多示例.
您的class定义几乎是正确的.错误是在实例化var Reply = new Reply();中.这将尝试重新定义分配给类名称的变量.同样,generator函数也应yield起作用.我详细说明了一些OP代码以显示工作示例.

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

更新1/12/2019

如@BugBuddy所建议,for..of循环看起来更好(但并非在所有情况下都有效).查看摘要中的更新行.

As suggested by @BugBuddy for..of loop looks even nicer (But doesn't work in all cases). See updated lines in the snippet.

这篇关于如何在JavaScript类中编写生成器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆