2017-05-03 35 views
1

你知道我的问题的解决方案吗? 我需要一个观察的包胶喜欢这里订阅的灵活的序列:Angular2与一些顺序订阅的自定义observables

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订阅到第一个代码块中。 为什么和我的更好的解决方案是什么?

+0

您不能等待Observable或Promise来完成。您只能订阅它才能在完成或发出活动时收到通知。你可以请添加saveExtendedData服务方法,因为我觉得你可以在那里做出改变? –

+0

对不起,我在第二个代码块中有一个错误。 “this.saveExtendedData()”方法应该是“this.saveData()”。 – Joeker

+0

在保存数据方法,而不是分配值的成功变量返回结果 –

回答

1

1日问题:为什么它不工作?

因为每个订阅是异步的。当你做this.saveCallbarrings().subscribe(...)内部认购的东西可以在任何时间(也许永远不会!)发生,因此,该程序继续到下一个指令,这是observer.next(success);,即有success初值。

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

Rx.Observables有so many operators处理这个异步的东西。在你的情况下,你需要的运营商是forkJoin。这个操作符让你给他一个流数组,并且它将订阅所有这些数据流,当它们全部完成时,它将为你提供一个数组,每个数据流都有一个结果。所以,你的代码将变成:

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不会执行任何代码,直到有人订阅它为止,所以您获得的副作用更少。

+0

非常感谢。您的解决方案对我成功了! – Joeker