2017-05-03 5 views
1

あなたの問題の解決方法をご存知ですか? 私はここのように観測可能にカプセル化サブスクライブの柔軟なシーケンス必要があります。一部のシーケンシャルサブスクリプションでAngular2カスタムオブザーバブル

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(); 
     } 
     }); 

メイン:私は私の提出方法に、この「レスポンス・コレクション」の結果と呼ばれる最後に

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); 
    }); 
    } 

を問題は、 "成功" varが最初のコードブロックに登録されるまで、角度が待たないということです。 なぜ私にとってより良い解決策はありますか?

+0

ObservableまたはPromiseの完了を待つことはできません。それを購読して、イベントが完了したときに通知を受けることができます。私はあなたがそこに変更を加えることができると感じるようにsaveExtendedDataサービスメソッドを追加してください? –

+0

申し訳ありませんが、私は2番目のコードブロックに間違いがあります。メソッド "this.saveExtendedData()"は "this.saveData()"でなければなりません。 – Joeker

+0

成功の変数に値を代入するのではなく、データを保存するメソッド –

答えて

1

第1質問:なぜ機能しないのですか?

すべてのサブスクリプションが非同期であるためです。 this.saveCallbarrings().subscribe(...)を実行すると、購読中のものはいつでも(おそらく決して!)起こることができないので、プログラムは次の命令、すなわちobserver.next(success);に続き、初期値はsuccessです。

第2質問:私にとって最善の解決策は何ですか?

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

関連する問題