如何有条件地使用 'flatmap' 运算符? (Angular 2/rxjs)

How to use the 'flatmap' operator conditionally ? (Angular 2/rxjs)

我想要实现的是有条件地运行一系列可观察值。

return observable.map(response => response)
       .flatmap(response1 => observable1(response1))
       .flatmap(response2 => observable2(response2))
       .flatmap(response3 => observable3(response3))

我需要检查 response1 并在需要时调用剩余的可观察对象,否则我需要 return response1 并中断执行等等。

我已经完成了以下 SO 问题,但它们似乎没有回答我的问题

Conditionally choose observable in RxJS

RXJS if with observable as conditional

我是 rxjs 的新手,所以如果问题看起来太蹩脚,请原谅我。

如有任何帮助,我们将不胜感激。

谢谢

这就像调用多个连续的 HTTP 请求,其中结果相互依赖。这是您要使用 concatMap() 的地方,因为它会等到回调函数返回的 Observable 完成。

很难从您的描述中确切地说出您想做什么,但是如果您需要停止传播结果(并避免调用不必要的 HTTP 请求),请查看 takeWhile() 运算符或简单的 filter() 运算符。

filter():

return observable
    .concatMap(response => response)
    .filter(response1 => response1.whatever === true)
    .concatMap(response1 => observable1(response1))
    .filter(response2 => response2.whatever === true)
    .concatMap(response2 => observable2(response2))
    .filter(response3 => response3.whatever === true)

如果项目未通过 filter 测试,这将不会进一步传播该项目。然而,源 observable 仍然可以发出将通过链的值。换句话说,filter 运算符没有完成链。

takeWhile():

return observable
    .concatMap(response => response)
    .takeWhile(response1 => response1.whatever === true)
    .concatMap(response1 => observable1(response1))
    .takeWhile(response2 => response2.whatever === true)
    .concatMap(response2 => observable2(response2))
    .takeWhile(response3 => response3.whatever === true)

如果 takeWhile() 中的任何一个结果为 false,它将完成链,并且不会发出其他值。

或者,您可以将所有 observable 组合成一个单独的 observable 并按如下方式订阅,

return response
         .concatMapTo(response1,(response2, response3) => 
             `${response2} ${response3}`
          );

使用

订阅它
data = response.subscribe(val => console.log(val)); // contains all three responses value

您仍然可以使用 response2response3 命名实例分别访问每一个。

使用不同的可观察对象订阅单个对象: 如果你想结合来自不同可观察对象的数据和属性,你可以看看这个 answer

我没有找到绕过运算符的简单方法,如果您决定跳过 n 个最后的运算符,您仍然必须通过所有运算符传递最后一个有效响应:

 return observable
   .flatmap(r => {
        return r.value > 1 ? observable1(r) : Observable.of(r);
   })
   .flatmap(r => {
        return r.value > 2 ? observable2(r) : Observable.of(r);
   })
   .flatmap(r => {
        return r.value > 3 ? observable3(r) : Observable.of(r);
   })

你可以这样做:

observable.map(res => res.json())
  .flatMap(json => {
      if (json.something === 'something') {
          return this.http.get('/anotherCall')
              .map(res => 'second response: ' + res);
      } else {
          return Observable.from(['just return something else']);
      }
  });

虽然只有两个电话,但您明白了。