2017-05-03 58 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