何か提案はありますか、これをより約束の連鎖スタイルでどのように書き直すことができますか?:
this.apiService.sendPutRequest('/api/users/activate', usrObj).pipe(
map(() => {
return this.apiService.sendGetRequest('/api/users/' + this.currentUserId).pipe(
map(data => {
return this.setActiveUser(data).pipe(
map(() => {
return this.apiService.sendGetRequest('api/tasks/user/' + this.currentUserId).pipe(
map(tasks => {
return this.taskService.setCurrentUserTasks(tasks);
})
);
})
);
})
);
})
);
switchMap を使用してオブザーバブルを処理し、 tap を使用して副作用を処理できます。そして、それは cold observable なので、サブスクライブする必要があります
エラー処理には、すべてのリクエストに catchError を使用します
this.apiService.sendPutRequest('/api/users/activate', usrObj).pipe(
catchError(err=> this.errorHandler(err)),
switchMap(() => this.apiService.sendGetRequest('/api/users/' + this.currentUserId)
.pipe(catchError(err=> this.errorHandler(err)))
),
tap(data => this.setActiveUser(data)),
switchMap(() => this.apiService.sendGetRequest('api/tasks/user/' + this.currentUserId)
.pipe(catchError(err=> this.errorHandler(err)))
),
tap(tasks => this.taskService.setCurrentUserTasks(tasks))
).subscribe()
そのためにSwitchMap
を使用します。
mainApiCall.pipe(
switchMap(result=>secondApiCall(result)),
switchMap(resultFromSecondApiCall=>thirdApiCall(resultFromSecond))
...
and so on
)
問題には単一のpipe
を使用してください。 map
、switchMap
、mergeMap
、tap
などのさまざまな連鎖可能な演算子をコンマで区切ります。
this.apiService.sendPutRequest('/api/users/activate', usrObj).pipe(
switchMap((results) => this.apiService.sendGetRequest('/api/users/' + this.currentUserId)),
tap((results) => this.setActiveUser(data)),
switchMap(() => this.apiService.sendGetRequest('api/tasks/user/' + this.currentUserId)),
tap((results) => this.taskService.setCurrentUserTasks(tasks))
);
簡略化:非同期API呼び出しなしで値を変換して別のオペレーターまたはサブスクリプションに渡す場合は、map
を使用し、変換せずに中間の値をキャッチする場合はtap
を使用します(例:ロギング用)。また、追加のAPI呼び出しをディスパッチするためのswitchMap
。