jcr*_*oll 3 rxjs angular-http angular
在下面的代码中,我有一个User对象,该对象可以具有与之关联的可变数量的帐户 ID。当用户更新时,应为用户对象中包含的每个帐户发出额外请求:
class User {
id: number;
accountIds: Array<number>;
}
// Side effects class
@Effect()
update$ = this.actions$
.ofType('USER_UPDATE')
.switchMap(action => {
let user = action.payload;
for (let accountId of user.accountIds) {
let account = { id: accountId, userIds: [user.id] };
// Is there any way to chain these api calls with switch maps
// and then finally switch map to the user request below?
return this.apiService.post(`/accounts/${account.id}`, account);
}
return this.apiService.post(`/users/${userid}`, user);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法使用 RxJS 使用switchMap(或类似的东西)将这些调用链接在一起,以便在所有后续请求完成之前,observable 不被认为是完整的,而不必编写某种自定义递归逻辑?
如果您只想使用 Observable 来处理它(这在效果中似乎是一个好主意),您可以这样做:
const { Observable } = Rx;
// DATA
const user = {
id: 'currentUserId',
accountIds: [
'accountId0',
'accountId1',
'accountId2',
'accountId3'
]
}
// MOCK BACKEND CALLS
const apiService = {
post: (url, data) => {
return Observable.of(`some response for ${url}`).delay(1000);
}
};
// HANDLE THE MULTIPLE HTTP CALLS
Observable
.from(user.accountIds)
.map(accountId => ({ id: accountId, userIds: [user.id] }))
.map(account => apiService.post(`/accounts/${account.id}`, account))
.concatAll()
.do(console.log)
.last()
.do(_ => console.log('Finished to chain the HTTP calls for accounts'))
.switchMap(_ => apiService.post(`/users/${user.id}`, user))
.do(console.log)
.subscribe();
Run Code Online (Sandbox Code Playgroud)
我做了一个 Plunkr,所以你可以看到它的实际效果:https ://plnkr.co/edit/xFWXyAJM6qm0XwMf4tmv?p=preview
这里有趣的部分是我们如何处理调用。
让我给你更多的细节:
from允许我们一个accountIds一个地发送observable :
.from(user.accountIds)
Run Code Online (Sandbox Code Playgroud)
然后我们可以为accountId我们想要发送到后端的每个对象构建:
.map(accountId => ({ id: accountId, userIds: [user.id] }))
Run Code Online (Sandbox Code Playgroud)
完成后,我们创建一个冷Observable,一旦我们订阅它,它将进行 HTTP 调用:
.map(account => apiService.post(`/accounts/${account.id}`, account))
Run Code Online (Sandbox Code Playgroud)
感谢concatAll,我们有您所期望的行为: 一一进行每个 HTTP 调用:
.concatAll()
Run Code Online (Sandbox Code Playgroud)
显示 HTTP 调用的响应:
.do(console.log)
Run Code Online (Sandbox Code Playgroud)
现在,我们想在users每个请求accounts完成后发出最终请求。last将帮助我们等待最后一个(这里是明显的队长):.last() 只需记录每个请求accounts都已完成
.do(_ => console.log('Finished to chain the HTTP calls for accounts'))
Run Code Online (Sandbox Code Playgroud)
对users
.switchMap(_ => apiService.post( /users/${user.id}, user))进行最后的 HTTP 调用输出响应
.do(console.log)
Run Code Online (Sandbox Code Playgroud)
当然,我们需要订阅,因为这是一个冷的 Observable,否则什么都不会发生。* 。订阅();
*:在你的 effect 中,你可能只想返回 Observable,因为 ngrx/effects 会为你订阅它;)
| 归档时间: |
|
| 查看次数: |
1839 次 |
| 最近记录: |