0

form/componentがあります。これは、「保存」を行うために4つの別々のAPI呼び出しを行う必要があります。本当に、それらのトランザクションのうちの1つだけが他の3つを待つ必要がありますが、私は4つすべてを安全にするために連鎖したがっていました。私はこれらの関数が実行されます(と応答が戻ってくる)ことを正確に順序を知っているので、私はログメッセージを持っているものをsave{number}機能の各内部角2私の4つのapi呼び出しが前の呼び出しが実行前に終了するのを待っているのはなぜですか?

save() { 
    this.save1(saveObject1) 
     .subscribe(response => { 
      if (response === 0) { 
       this.processErrorResult('save1'); 
      } 

      this.save2(saveObject2) 
       .subscribe(response2 => { 
        if (response2 === 0) { 
         this.processErrorResult('save1'); 
        } 

        this.save3(saveObject3) 
         .subscribe(response3 => { 
          if (response3 === 0) { 
           this.processErrorResult('save1'); 
          } 

          if (this.noErrorsInFirst3Saves()) { 
           this.save4(saveObject4) 
            .subscribe(response4 => { 
             if (response4 === 0) { 
              this.processErrorResult('save1'); 
             } 

             if (!this.hasErrors()) { 
              this.router.navigate(['confirmation']); 
             } 
            }); 
          } 
         }); 
       }); 
     }); 
} 

private save1(saveObject: any): Observable<int> { 
    this.api.save1(saveObject) 
     .subscribe(successful => { 
      return Observable.of(1); 
     }, failed => { 
      return Observable.of(0); 
     }); 
} 

private save2(saveObject: any): Observable<int> { 
    this.api.save2(saveObject) 
     .subscribe(successful => { 
      return Observable.of(1); 
     }, failed => { 
      return Observable.of(0); 
     }); 
} 

private save3(saveObject: any): Observable<int> { 
    this.api.save3(saveObject) 
     .subscribe(successful => { 
      return Observable.of(1); 
     }, failed => { 
      return Observable.of(0); 
     }); 
} 

private save4(saveObject: any): Observable<int> { 
    this.api.save4(saveObject) 
     .subscribe(successful => { 
      return Observable.of(1); 
     }, failed => { 
      return Observable.of(0); 
     }); 
} 

:ここ

は、私はそれを設定している方法です。

私は[保存]をクリックすると、それは[ほとんど]すぐにその後、私はそこに座って、クロムのdevのツールで私のコンソールウィンドウを見て、APIコールからの応答がでてくるし始める見ることができ、私の確認ページにリダイレクトします。

これらのトランザクションの明示的な連鎖を受け付けないのはなぜですか?私はAngularで知っています。promiseでこれを行うのはとても簡単で、.then(response => {});です。私はそれを考えることができ

唯一のものは異なっている、それはget/post/put/deleteのかどうか、EVERY API呼び出し用で、それは常にクロムのdevのツールのネットワークパネルの2つの呼び出しを示しています。最初のコールはRequestMethodOptionsに設定され、その後のコールは対応するget/post/put/deleteとなり、それに応じてRequestMethodが設定されます。

私が最近取り組んだ最近のアプリケーションの中で(複製された呼び出しを)見たことがないのですが(おそらく私はそれほど注意を払っていないかもしれません)、APIの標準操作手順ですコール。

ここに任意のアイデアはありますか?

編集:

以下ハリーの提案の回答を受けて、私はあなたの答えを実装しようとしているが、実装方法のまだ少し混乱しては、ここに私のセットアップを詳しく見です:

private save1(saveObject: any): Observable<number> { 
    if (saveObject.hasChanges()) { 
     return this.api.save1(saveObject) 
      .map(successful => { 
       return this.parseSaveResponse(successful, saveObject, true); // true indicates a successful API response 
      }) 
      .catch(failed => { 
       return this.parseSaveResponse(successful, saveObject, false); // false indicates a successful API response 
      }); 
    } else { 
     return Observable.of(-1); // no changes necessary, return immediately 
    } 
} 

private parseSaveResponse(response: any, saveObject: any, transactionSuccessful: boolean) { 
    this.logService.logTransaction({transactionType}, saveObject, response, transactionSuccessful); 

    if (!transactionSuccessful) { 
     // add to error list object to be displayed on the form 
     return 0; 
    } 

    return 1; 
} 

この時点にそれを取得する場合、それは言って.catch({});ラインで私にエラーを投げています:

Argument of type '(error: any) => 0 | 1' is not assignable to parameter of type '(err: any, caught: Observable<0 | 1>) => ObservableInput<{}>'. Type '0 | 1' is not assignable to type 'ObservableInput<{}>'. Type '0' is not assignable to type 'ObservableInput<{}>'.)

+0

あなたのコールチェーンにrxjsでswitchmap変換演算子に見えます。 Observableを入力として受け取り、それを使って他のAPIを呼び出すことができます。 Observable.forkJoinのメソッド – DOMZE

答えて

1

Theresの一因かもしれないあなたのコードでかなりの数の問題。まず、save1/save2/save3メソッドは、あなたが購読可能なあなたのAPIからObservableを返すだけです。

第2に、Typescriptに存在しないタイプを使用しています。 番号を使用してください。

private save1(saveObject: any): Observable<number> { 
    return this.api.save1(saveObject); 
} 
// or 
private save1(saveObject: any): Observable<number> { 
    return this.api.save1(saveObject).map(response => 1).catch(response => 0) 
} 

放出されたアイテムを変更したい場合は、放出されたアイテムを他のものにマッピングするマップ演算子を追加できます。

最後に、オブザーバブル内からオブザーバブルを購読することは避けてください。 flatMapオペレータを使用して観測値を連鎖させることができます。 Observableによって放出されたアイテムをObservablesに変換し、それらの放出を単一のObservableに平坦化します。

save() { 
    this.save1(saveObject1) 
    .flatMap(response1 => this.save2(saveObject2)) 
    .flatMap(response2 => { 
     if (response2 === 0) { 
     // handle error 
     } 
     return this.save3(saveObject3); 
    }) 
    .flatMap(() => this.save4(saveObject4)) 
    .subscribe(response4 => { 
     // do redirect 
    }); 
    } 

http://reactivex.io/documentation/operators/flatmap.html

+0

申し訳ありませんが、彼らはObservable を既に返しています。これは擬似コードの書き込みであり、C#の代わりにtypescriptの世界にあったことを忘れています。あなたの応答の残りの部分を介して... – ganders

+0

上記の私の編集を参照してください... – ganders

+0

私はそれが仕事を得たと信じて....私はいくつかのより多くのテストで確認したら、私はあなたの質問を更新して、ありがとうございました[私の考え] ... – ganders

0

私は、あなたの観測値を "返す"必要があると思います。例:

変更この:

this.api.save1(saveObject) 

へ:

return this.api.save1(saveObject) 
+0

を調べるには、 'this.api.save1()'の各呼び出しに '.subscribe'があり、' Observable.of({number }); '? – ganders

+0

@gandersはい。あなたが指定した場所に戻り値を追加するとすぐに、戻り値 – vidalsasoon

+0

が必要になります。vscodeは、そのブロック全体で赤いエラー行を投げます: 'TypeサブスクリプションをタイプObservableに割り当てることができません。 – ganders

関連する問題