具有一些顺序订阅的Angular2自定义可观察对象

时间:2017-05-03 06:29:11

标签: angular promise observable sequential

你知道我的问题的解决方案吗? 我需要一个灵活的订阅序列,在这里可以观察到:

saveData() {
    return new Observable((observer) => {
      let success = true;

      if(example === true) {
        this.saveCallbarrings().subscribe((response) => {
          // this response was ignored from angular
          success = (response === true);
        });
      }

      if(example2 === true) {
        this.saveCallbarrings().subscribe((response) => {
          // this response was ignored from angular too
           success = (response === true);
        });
      }

      // and so on ... in the end I need a result of all responses
      observer.next(success);
    });
  }

最后,我调用了这个"响应 - 收集"的结果。在我的提交方法中:

onSubmit() {
// Validations and others
...
if(this.isNew) {
        observable = this.create();
      } else {
        observable = this.update();
      }

      return observable.subscribe(success => {
        if(success == true) {
          let subscription = this.saveData().subscribe(successFinished => {
            // And here is the problem, because this var doesnt have the correct response
            if(successFinished === true) {
              this.alertService.success('ALERT.success_saved', {value: 'ALERT.success_edit_user', param: {user: this.user.username}});
            }
          });

          subscription.unsubscribe();
        }
      });

主要问题是角度不会等到成功" var在第一个代码块中订阅。 为什么以及对我来说什么是更好的解决方案?

1 个答案:

答案 0 :(得分:1)

第一个问题:为什么它不起作用?

因为每个订阅都是异步的。当你执行this.saveCallbarrings().subscribe(...)时,订阅中的内容可能随时发生(可能永远不会!),因此程序继续执行下一条指令observer.next(success);,其初始值为success

第二个问题:对我来说最好的解决方案是什么?

Rx.Observables有so many operators来处理这种异步的东西。在您的情况下,您需要的运算符是forkJoin。这个操作符允许你向他传递一个流数组,它将订阅所有这些流,当它们全部完成时,它将为你提供一个数组,其中包含每个流的每个resuts。所以你的代码将成为:

saveData() {
    return Rx.Observable.defer(() => {
        let streams = [];
        if(example === true) {
            streams.push(this.saveCallbarrings());
        }
        if(example2 === true) {
            streams.push(this.saveCallbarrings());
        }

        // And so on

        return Rx.Observable.forkJoin(streams);
    });
}

话虽如此,我不确定为什么你会对同一个this.saveCallbarrings()做多次订阅,我想这只是为了让问题更简单,作为一个例子。

此外,我在这里使用.defer()而不是创建。有了这个,您可以返回另一个流,它将订阅它并将其传递给观察者。执行defer和不执行任何操作(即设置流并只返回forkJoin)之间的区别在于defer在有人订阅之前不会执行任何代码,因此您可以减少支持的效果。