javascript ES6迭代器的用例

carvr3hs  于 2022-12-28  发布在  Java
关注(0)|答案(2)|浏览(251)

使用ES迭代器的理由是什么?我知道生成器函数(带 * 的函数)上的异步操作是什么。纯迭代器的其他用例是什么?
请给予我一些真实的生活中的例子,这与node.js或浏览器的使用无关。

k2fxgqgv

k2fxgqgv1#

主要有两个原因:
1.诸如for/of、spread运算符、析构赋值等语言特性可以构建为在任何支持标准迭代器接口的对象上工作。
1.使用集合的程序员既可以直接使用迭代器,也可以通过依赖于它的语言特性间接使用它,并且他们可以通过许多方式通用地与集合接口,而不必知道它是什么类型的集合。
作为ES6中的语言特性的一个示例,在语言中使用迭代器标准的是,您可以具有如下语言构造:

for (x of someObj) { ... }

并且for/of逻辑只使用someObj上的迭代器接口,它不需要知道它可以迭代的所有对象类型的任何细节,因此,可以将for/of用于支持标准迭代器的任何类型的对象,例如,可以将它用于数组、Map、集合、或者您创建的任何支持迭代器接口的自定义对象。
给定对象上的迭代器实现定义了哪些元素是可迭代的,以及它们将以什么顺序出现。
坦率地说,我发现使用依赖于迭代器的语言特性(如for/of)比实际直接使用迭代器要常见得多,这样我就可以以标准的方式使用集合,而不必知道它是什么类型的集合。
在我自己的代码中,我发现能够在不知道对象是什么类型的情况下迭代对象是非常方便的,这允许我设计一个接口,可以传递SetArray,有时甚至是Map,只要我想做的是迭代集合中的项,我不需要关心它是什么,也不需要编写任何不同的代码。如果调用者碰巧手边有一个Set,他们不必为了调用API而将其转换为Array-他们只需传递Set。API中的代码不必检查传递给它的类型来调整其行为。
迭代器也是惰性求值的。因此,在开始迭代之前,不需要构建整个集合的临时数组。这可以使迭代更有效,特别是当集合很大和/或迭代没有遍历整个集合时。
迭代器可以是无限的。例如,你可以有一个斐波那契迭代器来表示一个无限序列。
除了for/of之外,其他使用迭代器的ES6特性包括:

spread syntax
yield*
destructuring assignment
Array.from()

这些特性可以用于任何支持标准迭代器的对象。
有关详细信息,请参阅以下文章:
Iterables and iterators in ECMAScript 6
ES6 Iterators and Generators in Practice

hzbexzde

hzbexzde2#

export const execInBatch = async <T>(
  items: T[],
  batchSize: number,
  callback: (item: T[]) => Promise<void>
) => {
  for (const batch of asChunks(items, batchSize)) {
    await callback(batch);
    await new Promise((resolve) => setTimeout(resolve, 1000));
  }
  return true;
};

export function* asChunks<T>(arr: T[], chunkSize: number) {
  let chunk = [];
  for (const item of arr) {
    chunk.push(item);
    if (chunk.length === chunkSize) {
      yield chunk;
      chunk = [];
    }
  }
  if (chunk.length > 0) {
    yield chunk;
  }
}

(async () => {
  const items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
  const fn = async (item: number[]) => {
    console.log(item);
    return;
  };
  const data = await execInBatch(items, 2, fn);
  console.log(data);
})();

我为批处理任务创建了这个函数。

相关问题