Javascript 发电机如何排气?

Javascript 发电机如何排气?,javascript,ecmascript-6,iteration,generator,Javascript,Ecmascript 6,Iteration,Generator,我将every作为生成器来实现,以提前中断迭代: const every = (f, iter) => function* () { for (const value of iter) { const ret = f(value); yield ret; if (!ret) break; } } (); const exhaustEvery = iter => { for (value of iter) { if (!value)

我将
every
作为生成器来实现,以提前中断迭代:

const every = (f, iter) => function* () {
  for (const value of iter) {
    const ret = f(value);
    yield ret;
    if (!ret) break;
  }
} ();

const exhaustEvery = iter => {
  for (value of iter) {
    if (!value)
      return false;
  }

  return true;
};

exhaustEvery(every(x => x % 2 === 1, [1,3,5])); // true

这看起来相当麻烦,因为我必须为每个迭代函数实现一个单独的排气函数。这是否表明生成器的使用不正确?

没有什么意义,因为每个都是一个生成器,因为它本身不生成值,它只返回true或false,因此可能是:

 function every(iterator, predicate) {
    let value, done;
    do {
      ({ value, done } = iterator.next());
      if(!predicate(value)) return false;
    } while(!done)
    return true;
}

every([1, 2, 3].values(), it => it < 3) // false
函数every(迭代器、谓词){
让价值,去做;
做{
({value,done}=iterator.next());
如果(!谓词(值))返回false;
}而(!完成)
返回true;
}
every([1,2,3].values(),it=>it<3)//false

没有什么意义,
每个
都是一个生成器,因为它本身不生成值,它只返回true或false,因此可能是:

 function every(iterator, predicate) {
    let value, done;
    do {
      ({ value, done } = iterator.next());
      if(!predicate(value)) return false;
    } while(!done)
    return true;
}

every([1, 2, 3].values(), it => it < 3) // false
函数every(迭代器、谓词){
让价值,去做;
做{
({value,done}=iterator.next());
如果(!谓词(值))返回false;
}而(!完成)
返回true;
}
every([1,2,3].values(),it=>it<3)//false

有些发电机无法耗尽,例如:

函数*fibonacci(n){
常量无穷=!n&&n!==0;
设电流=0;
设next=1;
而(无限| | n--){
屈服电流;
[当前,下一步]=[下一步,当前+下一步];
}
}
//设[…first10]=斐波那契(10);
//警报(前10);
//上面是有限发电机,显示了如何将其耗尽,
//但是,如果它是按照以下方式启动的:
设noexhaust=fibonacci();
警报(noexhoust.next().value);
警报(noexhoust.next().value);
警报(noexhoust.next().value);
警报(noexhoust.next().value);

//等等…
有些发电机无法耗尽,例如:

函数*fibonacci(n){
常量无穷=!n&&n!==0;
设电流=0;
设next=1;
而(无限| | n--){
屈服电流;
[当前,下一步]=[下一步,当前+下一步];
}
}
//设[…first10]=斐波那契(10);
//警报(前10);
//上面是有限发电机,显示了如何将其耗尽,
//但是,如果它是按照以下方式启动的:
设noexhaust=fibonacci();
警报(noexhoust.next().value);
警报(noexhoust.next().value);
警报(noexhoust.next().value);
警报(noexhoust.next().value);

//依此类推……
如果您知道生成器将结束(生成器不保证结束),您可以使用
[…res]
来传播这些值。对于生成器,您可以只查看最后一个值:

constevery=(f,iter)=>function*(){
for(国际热核实验堆常数值){
常数ret=f(值);
收益率;
如果(!ret)中断;
}
}();
设res=[…every(x=>x%2==1[1,3,5]);//真的
console.log(res[res.length-1])
res=[…每(x=>x%2==1[1,3,5,8,2,5,9]);//假的

console.log(res[res.length-1])
如果您知道自己的生成器将结束(哪些生成器不保证),则可以使用
[…res]
分散这些值。对于生成器,您可以只查看最后一个值:

constevery=(f,iter)=>function*(){
for(国际热核实验堆常数值){
常数ret=f(值);
收益率;
如果(!ret)中断;
}
}();
设res=[…every(x=>x%2==1[1,3,5]);//真的
console.log(res[res.length-1])
res=[…每(x=>x%2==1[1,3,5,8,2,5,9]);//假的

console.log(res[res.length-1])
为什么需要生成器?我只想在不想一次性耗尽迭代器的情况下尽快使用生成器函数。@NinaScholz我想要every(和其他迭代函数)要成为数据结构不可知论者,我需要提前退出跟踪为什么需要生成器?我只想在不想一次性耗尽迭代器的情况下使用生成器函数。@NinaScholz我希望每个(和其他迭代函数)都是数据结构不可知论者,我需要提前退出trait@carcigenicate这还是懒惰,,迭代器只有在找到第一个falsy值之前才会被使用。你是对的。我想错了。我的错。这只适用于each,不适用于其他迭代函数。@dafunc对,但问题是关于
each
?@carcigenicate这仍然是懒惰的,迭代器只会在找到第一个falsy值之前被使用。你是对的。我想错了。我的不好。这只适用于each,不适用于其他迭代函数。@dafunc对,但问题是关于
each
?这很有趣,但在这种情况下,可能在其他情况下不是很有效,因为它可能会创建一个巨大的中间值。@dafunc,是的。如果您追求的是效率,那么根本不清楚您为什么要创建一个生成器,然后对其进行迭代,而不是只对输入调用
array.every()
。这很有趣,但在这种情况下,或者在其他情况下,效率不是很高,因为它可能会创建一个巨大的中间值。@DaFunc,是的。如果您追求的是效率,那么根本不清楚您为什么要创建一个生成器,然后对其进行迭代,而不仅仅是对输入调用
array.every()