promises 的函数式操作(例如过滤)

Functional operations (such as filtering) on promises

我正在同时执行多个查询并根据它们创建一系列承诺。我希望生成的数组仅具有从查询返回的某些属性,并且我想过滤其他属性(但这些操作实际上可以是任何东西)。目前,我有:

Promise.all(Ids.map(Id => query(Id)
  .then(result => result.Item)
)).then(results => results.filter(Boolean));

内部result.Item还是并行做的,所以我觉得这样还可以,但我不喜欢这样,原因有二:

  1. 我有一个内部/嵌套的承诺链,我想展平
  2. 外部过滤必须等待所有承诺完成(预期),然后迭代整个结果(坏)。最好不要首先添加空项。

是否有更好的方法来对承诺集合执行功能操作?

一种方法是使用 Reactive Extensions 库,它提供了一种将不同的异步模型集成到概念 "stream" 模型中的方法。例如。你上面的代码(假设 Ids 是一个数组并且 query return 是一个承诺)会变成这样:

Observable.from(Ids)
    .flatMap(id => query(id))
    .map(result => result.Item)
    .filter(item => item.filterByThis) // Not sure what Boolean is supposed to be in your code
    .toArray();

假设 Ids 是一个 number[],我们首先生成一个 Observable<number>,然后将它传递给各种看起来很熟悉的运算符来转换和过滤流,最后使用 toArray 得到一个 observable,它发出任何类型的单个数组 result.Item 应该是。

您可以将 Observables 视为对异步操作的承诺概念的概括,return 任意数量的值,而不仅仅是一个。这是一个强大的范例,Rx 库在许多语言中都非常流行。您可以阅读更多相关信息 here or get started with this npm 包。