1

我想同时使用处理一个可观察对象列表,flatMap然后在处理所有内部可观察对象时发出一个空值。有没有一种优雅的方式来实现这一点,即使用单个运算符?

这是示例:

const { of, from } = Rx.Observable;

from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
  .mergeMap(number => multiply(number), 2) // processing two numbers at a time
  .last() // waiting for all inner observables to complete
  .map(_ => undefined) // casting a value returned by last() to an empty value
  .subscribe()
;

function multiply(number) {
  return of(number * 2) // multiplying the number
    .delay(200) // adding a slight delay
  ;
}

我知道我可以使用toArray()last()等待所有内部可观察对象完成,但随后我需要使用map()运算符将​​其转换为空值(如我上面的示例所示)。

我想,我正在寻找具有以下语义的运算符:emit X when source observable completes,例如:

from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
  .mergeMap(number => multiply(number), 2)
  .emitOnComplete(undefined)
  .subscribe(console.log) // we should get undefined here
;
4

2 回答 2

2

实际上有一个偷偷摸摸的解决方案使用reduce()它只在其源 observable 完成时发出一次。您可以使用它来忽略所有值并只返回种子值:

from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
  .pipe(
    mergeMap(number => multiply(number), 2),
    reduce((acc, value) => acc, undefined),
  )
  .subscribe(console.log);

现场演示:https ://stackblitz.com/edit/rxjs-tx6bbe

顺便说一句,有趣的事实:在 Angular 的 Router 包reduce()中使用了相同的技巧(只是没有种子值)。

于 2020-03-24T20:28:00.617 回答
0

到目前为止,我设法找到的最方便的方法是将ignoreElements运算符与endWith结合起来:

from([1, 2, 3, 4, 5])
  .mergeMap(number => multiply(number), 2)
  .ignoreElements()
  .endWith(undefined)
  .subscribe(console.log) // getting undefined here
;

但是,如果有一个单独的操作员来做这件事,那就太好了。

于 2020-03-24T19:42:54.537 回答