2

假设我们有一个异步生成器:

exports.asyncGen = async function* (items) {
  for (const item of items) {
    const result = await someAsyncFunc(item)
    yield result;
  }
}

是否可以映射此生成器?基本上我想这样做:

const { asyncGen } = require('./asyncGen.js')

exports.process = async function (items) {
  return asyncGen(items).map(item => {
    //... do something
  })
}

截至目前.map无法识别异步迭代器。

另一种方法是使用for await ... of ,但这远不及优雅.map

4

2 回答 2

3

提供此方法迭代器方法提案仍仅处于第 2 阶段。您可以使用一些polyfill,或者编写自己的辅助函数: map

async function* map(asyncIterable, callback) {
    let i = 0;
    for await (const val of asyncIterable)
        yield callback(val, i++);
}

exports.process = function(items) {
    return map(asyncGen(items), item => {
       //... do something
    });
};
于 2021-06-01T19:32:48.563 回答
2

另一种方法是使用for await ... of,但这远不及优雅.map

对于一个优雅而高效的解决方案,这是一个使用iter-ops库的解决方案:

import {pipe, map} from 'iter-ops';

const i = pipe(
    asyncGen(), // your async generator result
    map(value => /*map logic*/)
); //=> AsyncIterable
  • 它很优雅,因为语法干净、简单,并且适用于任何可迭代或迭代器,而不仅仅是异步生成器。
  • 它更加灵活和可重用,因为您可以将许多其他运算符添加到同一管道中。

由于它生成标准 JavaScript AsyncIterable,您可以执行以下操作:

for await(const a of i) {
    console.log(a); //=> print values
}

PS 我是iter-ops的作者。

于 2021-12-14T10:49:51.653 回答