Javascript 如何克隆ES6生成器?

Javascript 如何克隆ES6生成器?,javascript,ecmascript-6,clone,generator,Javascript,Ecmascript 6,Clone,Generator,我正在尝试使用生成器在ES6中创建一个列表monad。为了使它工作,我需要创建一个迭代器的副本,该迭代器已经使用了几个状态。如何在ES6中克隆迭代器 function* test() { yield 1; yield 2; yield 3; } var x = test(); console.log(x.next().value); // 1 var y = clone(x); console.log(x.next().value); // 2 console.log(

我正在尝试使用生成器在ES6中创建一个
列表
monad。为了使它工作,我需要创建一个迭代器的副本,该迭代器已经使用了几个状态。如何在ES6中克隆迭代器

function* test() {
    yield 1;
    yield 2;
    yield 3;
}

var x = test();
console.log(x.next().value); // 1
var y = clone(x);
console.log(x.next().value); // 2
console.log(y.next().value); // 2 (sic)
我试过从
lodash
克隆
clone
cloneDeep
,但都没有用。以这种方式返回的迭代器是本机函数,并在内部保持其状态,因此似乎无法使用自己的JS代码来实现

迭代器[…]在内部保持它们的状态,所以似乎没有办法

是的,这是有充分理由的。无法克隆状态,否则可能会对生成器进行过多的篡改


然而,通过记忆第一个迭代器的序列并在以后再次生成它,可以创建与第一个迭代器并行运行的第二个迭代器。但是,应该只有一个迭代器真正驱动生成器—否则,您的哪个克隆可以发送
next()
参数?

我为JavaScript编写了一个do符号库。为了解决我提出的可变生成器问题,它通过维护输入值的历史记录并重放它们来模拟不可变生成器,以在任何特定状态下克隆生成器。

你不能克隆生成器,它只是一个没有状态的函数。可以有状态的,因此可以克隆的,是调用生成器函数得到的迭代器

这种方法缓存中间结果,以便克隆迭代器可以在必要时访问它们,直到它们“赶上”。它返回一个既是迭代器又是iterable的对象,因此您可以对其调用
next
,也可以对其调用
for…of
。任何迭代器都可以传入,因此理论上可以通过传入
array.values()
在数组上克隆迭代器。无论哪个克隆在迭代中的给定点首先调用
next
,都会将参数传递给
next
(如果有),并反映在基础生成器中的
yield
值中

函数克隆计数器(it){
var VAL=[];
返回函数make(n){
返回{
下一个(arg){
const len=vals.length;
如果(n>=len)vals[len]=it.next(arg);
返回VAL[n++];
},
clone(){return make(n);},
扔(e){如果(它。扔)它。扔(e);},
return(v){if(it.return)it.return(v);},
[Symbol.iterator](){返回此;}
};
}(0);
}
函数*gen(){
产量1;
产量2;
产量3;
}
var it=克隆畸形因子(gen());
console.log(it.next());
var clone=it.clone();
log(clone.next());

console.log(it.next())记住以前的值会有所帮助,但这不是问题的关键。我有一个选项,可以将参数存储到
next
,这样我就可以从同一个生成器中创建另一个迭代器,并重新运行它直到同一点。这种方法的问题是ES中的函数不是纯函数,而且在同一个生成器的第二次运行中,我可能会得到其他结果。我想,如果没有人对克隆迭代器有更好的想法,我最好进入一个名为“harmony”的邮件列表,在那里问一个问题。也许我对你的用例理解得不够透彻。你真的是纯的吗?您是否将参数传递给
.next()
?这两个迭代器(原始迭代器和克隆迭代器)实际是如何使用的(由什么使用的)?我正在尝试运行以下类似于Haskell的非确定性m monad()的代码。对于数组
iter.next(prev.value)
的每个元素
x
,我需要将其作为参数递归地传递给下一个名为
next
的元素。这样,
yield
之后的代码将以不同的“返回值”运行多次,因此不确定。我认为生成器根本不支持这种情况,可能您需要备份并使用显式延续。不过,我会调查一下,不确定性的monad听起来很有趣。如果生成器支持这一点,它将窃取Haskell的主要功能:在不同环境中运行相同代码的能力。在我看来,启用它的最佳方法是侵入
再生器的源代码,并将其展示给ES6社区。这可不容易:/实现得不错,+1!您可能还希望转发
抛出
返回
调用。如果您只对迭代器感兴趣,则不应通过
arg
。Sweet!我也在做同样的事情,来到这里:D