如何在JavaScript类中编写生成器?
通常,我编写的代码如下:如何在JavaScript类中编写生成器?,javascript,ecmascript-6,Javascript,Ecmascript 6,通常,我编写的代码如下: //definition exports.getReply = function * (msg){ //... return reply; } //usage var msg = yield getReply ('hello'); class Reply{ *getReply (msg){ // yield something here, otherwise you should use a normal function
//definition
exports.getReply = function * (msg){
//...
return reply;
}
//usage
var msg = yield getReply ('hello');
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
但是如何在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;
}
}
}
这两种方法似乎都是错误的答案。那么,我如何才能在类中正确地编写生成器函数呢?生成器是带有
.next()
的函数,用于获取收益率
'ed值,或者您可以收益率
生成器函数,让它知道在遇到收益率
语句时无需“等待”即可调用.next
(reply.getReply().next(fn)
)
您的第二段代码几乎是正确的:
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`?
首先,在ES6中工作时,请使用const
或let
,并且仅对类使用大写变量。
您正试图用var Reply=
语句覆盖class Reply
语句,这是不可能的,因为已经声明了标识符“Reply”
您正在寻找的答案如下:就像在第一个示例中所做的那样,您应该
产生
生成器函数,因此您的函数应该如下所示:
//definition
exports.getReply = function * (msg){
//...
return reply;
}
//usage
var msg = yield getReply ('hello');
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
编辑:添加更多示例。
您的
class
定义(几乎)是正确的。错误发生在实例化var Reply=new Reply();
中。这试图重新定义分配给类名的变量。另外generator
函数应该产生一些东西。我详细阐述了一些操作代码来展示工作示例
类回复{
//添加用于测试目的
构造函数(…参数){
this.args=args;
}
*getReply(msg){
for(让arg在这个.args中){
让reply=msg+this.args[arg];
//发电机应该产生一些东西
作出答复;
}
//下一个调用返回(产生){done:true,value:undefined}
}
*其他乐趣(){
产生这个。getReply('很高兴认识你');//产生生成器对象
产生这个.getReply('See you');//是的,这个可以访问
//下一个调用产生{done:true,value:undefined}
}
*伊文莫尔(){
yield*this.getReply('I miss you');//产生生成器结果
收益*this.getReply('我更想念你');
}
}
//现在测试一下我们有什么
const reply=新回复(“彼得”、“詹姆斯”、“约翰”);
//由于全局范围的原因,这里的let和var是可互换的
var r=reply.getReply('Hello');
var msg=r.next();//{done:false,值:“…”}
而(!msg.done){
console.log(msg.value);
msg=r.next();
}
var other=reply.otherFun();
var o=other.next();//{done:false,value:Generator}
而(!o.done){
设gen=o.value;
msg=下一代();
而(!msg.done){
console.log(msg.value);
msg=下一代();
}
o=其他。下一步();
}
var more=reply.evenMore();
msg=more.next();
而(!msg.done){
console.log(msg.value);
msg=more.next();
}
//2019年1月12日更新
//更多例子
for(让r of reply.getReply('for')){
控制台日志(r);
}
for(让r表示答复。evenMore()){
控制台日志(r);
}
//请注意,由于发电机功能中缺少星号(*),以下操作不起作用
for(让r表示reply.otherFun()){
控制台日志(r);
}
TL;谷歌困惑访客的灾难恢复:
在Javascript中,如何在类中编写生成器函数
A类{
*值(){
产生“价值”;
收益率*[1,2,3,4,5];
}
}
语法上是正确的。它可以工作。欢迎您,现在请您离开。“这两个方法似乎都是错误的答案”-这是什么意思?您在类中定义生成器函数的方式与“普通”生成器函数的方式相同。@zerkms您能举个例子吗?我尝试时,它会产生语法错误。您的代码(第一个示例中的类定义)语法正确,运行时没有语法错误。您需要使用不同的变量名,如var reply=new reply();
@Bergi,这个问题与引用的问题不同,这个问题是关于分类的,另一个是关于对象文字的“您应该yield
generator函数”-不。答案中的代码会生成生成器,您也不应该这样做。您应该yield*
generators。“您实际上是在用var Reply=语句覆盖类Reply语句。”这是不可能的。“const Reply=yield this.getReply();“为什么const reply=
?”yield reply.getReply('foo');“yield
在生成器函数之外?@Bergi你说的yield*
是什么意思?没有yield*
这样的东西吗?它是function*something(){}
和yield
。@zeroflagL我更正了覆盖解释,它实际上会返回一个错误,即标识符“Reply”
已经存在。const Reply=
,因为它是Reply的一个新实例,所以您可能不希望它被其他东西覆盖,而且不可能调用yield
将在生成器函数外部调用,但这是实现这一点的方法。我将更改答案,以包含更多有关如何在生成器外部获取返回值的代码function@CreasolDev当然有,向上看。@Bergi好的,很抱歉,我不知道,但是如果这只是他想要的返回值,就没有理由使用 yield*
使用类似co.wrap的东西似乎更符合逻辑,它将返回一个带有所需值的承诺(在生成器之外)Alex,我想知道为什么您使用yield this.getReply('nike to meeting you');
而不是yield*this.getReply('nike to meeting you'))
。getReply
本身是一个生成器函数,不是吗?在您的示例中,您能展示一下for…of
的用法吗?这不会产生比while循环更好的代码吗?@bugbddy谢谢您的建议,并查看更新的答案。如果您感兴趣,请使用Symbol.iterator