Rxjs - 将异步响应与同步响应合并

时间:2017-01-19 22:36:58

标签: rxjs rxjs5

我开始使用RxJs 5进行功能链,并且非常享受它。我注意到我经常遇到的一种模式,但找不到使用RxJs方法解决它的方法。

我使用value获取某些异步数据,并使用将它们与值本身合并。

让我用代码告诉你:

Rx.Observable.fromPromise(somePromise) // doesn't really matter
  .flatMap(value => {  // this is the original value I have
    const promise = aFunctionThatReturnsPromise(value);
    return Promise.all([promise, value])); // I created a promise using this value, but I still want to keep value as well
  })
  .map(([promiseValue, originalValue]) => ({ // I merge new produced values with the value itself and get rid of array.
    value1: promiseValue.value1,
    value2: promiseValue.value2
    originalValue: originalValue
  }))
  // ...rest of the chain...

正如可以看到的,这意味着要创建一个与Promise.all合并的承诺,只是为了保持value和一个与map的清理阶段,以便为链接的后续部分创造更好的效果

这种模式是否有内置 RxJs构造?或者是否有另一种方法可以产生更清晰,更易理解的解决方案?

2 个答案:

答案 0 :(得分:2)

当你想要将输入值与输出值结合起来时,人们倾向于写:

Rx.Observable.of('foo')
  .mergeMap(i => aFunctionThatReturnsPromise(i)
    .map(asyncResult => ({ foo: i, result: asyncResult})
  )

使用mergeMap resultSelectorflatMap if rxjs4)可以简化此模式,如下所示:

Rx.Observable.of('foo')
  .mergeMap(
    i => aFunctionThatReturnsPromise(i),
    (i, asyncResult) => ({ syncValue: i, asyncResult })
  )
// ... rest of the chain

这使您可以访问原始输入值和接收的每个输出值。额外的好处是mergeMap会将您的承诺包含在一个可观察的内容中而不使用Rx.Observable.fromPromise()

答案 1 :(得分:1)

使用纯RxJS,嵌套可观察链以保持先前值在上下文中是常见的:

Rx.Observable.fromPromise(somePromise)
  .flatMap(value =>
    Rx.Observable.fromPromise(aFunctionThatReturnsPromise(value))
      .map((promiseValue) => ({
        value1: promiseValue.value1,
        value2: promiseValue.value2,
        originalValue: value
      }))
  )
// ...rest of the chain...

如果使用太多,可以快速失控,所以你通常会尽快减少数据(并回到外部流)。