发电机如何排气?

问题描述 投票:0回答:4

我将

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

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

javascript ecmascript-6 iteration generator
4个回答
2
投票

every
是一个生成器没有什么意义,因为它本身不生成值,它只是返回 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

1
投票

如果您知道生成器将结束(生成器不保证),您可以使用

[...res]
分散值。对于您的生成器,您可以只查看最后一个值:

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


let res = [...every(x => x % 2 === 1, [1, 3, 5])]; // true
console.log(res[res.length - 1])

res = [...every(x => x % 2 === 1, [1, 3, 5, 8, 2, 5, 9])]; // false
console.log(res[res.length - 1])

但是,如果您执行所有这些操作只是为了从生成器生成列表,则可能有更好的方法使用简单的函数。


0
投票

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

function *fibonacci(n) {
  const infinite = !n && n !== 0;
  let current = 0;
  let next = 1;
  
  while (infinite || n--) {
    yield current;
    [current, next] = [next, current + next];
  }
}

// let [...first10] = fibonacci(10);
// alert(first10);
// the above is finite generator and shows how you can exhaust it,
// but what if it is initiated like the following:

let noexhaust = fibonacci();
alert(noexhaust.next().value);
alert(noexhaust.next().value);
alert(noexhaust.next().value);
alert(noexhaust.next().value);
// and so on...

那么,如果你的代码面对一个永无止境的生成器,它应该有什么行为?


0
投票

从 ECMAScript 2025 开始,我们有了迭代器辅助方法

every
(不要与同名的 Array 方法混淆)。对于您的示例,这将是:

const iter = [1,3,5].values(); // Get an iterator helper object
const result = iter.every(x => x % 2 === 1);
console.log(result); // true

© www.soinside.com 2019 - 2024. All rights reserved.