从数据数组中创建observable并将所有这些链接在一起

时间:2018-03-02 17:23:46

标签: angular rxjs rxjs5

我有以下要求:

  • 我有一个数据数组
  • 对于数组中的每个项目,我需要执行一次调用,产生一个Observable
  • 我需要将所有这些可观察的链接在一起
  • 如果其中一个observable导致错误响应,我需要返回false
    • 进一步观察不应该继续

上下文是Angular中的一个守护者,它使用canActivate()返回一个Observable< boolean>

我想避免在后卫(伪代码)中进行构造:

// the actions to check
var actions = ['x', 'y', 'z'];

canActivate() : Observable<boolean> {
    return this.performAction(actions[0]).subscribe(result => {
      if(result){
        this.performAction(actions[1]).subscribe(result2 => {
           if(result2){
               this.performAction(actions[2]).subscribe(result3 => {
                 ...
               };
           }
       });
   }
   //result = false;
 };
}

1 个答案:

答案 0 :(得分:1)

你可以这样做:

import { Observable, Subject, ReplaySubject } from 'rxjs';

const actions = ['x', 'y', 'z'];

const performAction = (action): Observable<boolean> => {
  if (action === 'y') {
    return Observable.of(false);
  }
  return Observable.of(true);
}

const observable = Observable.from(actions)
  .concatMap(a => performAction(a))
  .multicast(new ReplaySubject(1),
    s => s.takeWhile(result => result !== false).concat(s.take(1))
  );

observable.subscribe(console.log);

查看实时演示(开放式控制台):https://stackblitz.com/edit/rxjs5-hnzwtt?file=index.ts

最重要的部分是multicast运算符,它会在收到false之前通过所有内容。然后,此false值是完成链之前的最后一个值(感谢concat)。

输出结果为:

true
false