查找方法具有以下签名
find(): Observable<User[]>
它返回一个发出用户列表的可观察对象,可能如下所示:
[{ user_1 }, { user_2 }]
我的目标是对列表中的每个用户运行异步操作。该异步操作应该通过添加一些字段来修改元素。最后应该发出更新的用户列表。这是我尝试过的:
return this.service.find()
.mergeMap((users: User[]) => Observable.from(users))
.mergeMap((user: User) => {
return this.anotherService.getAdditionalData(user.id)
.map((res: any) => {
// return edited user
})
})
// How to return User[] here?
使用第一个 mergeMap 为列表中的每个用户创建一个可观察对象。然后对于每个用户可观察到的另一个异步操作。异步操作返回编辑后的用户。
我的问题是,最后,如何返回包含已编辑用户的用户列表。或者如何将编辑后的用户收集到列表中并返回该列表?
最佳答案
我认为这可以满足您的需求:
function asyncOperation(user) {
return Rx.Observable
.timer(3000 * Math.random())
.map(() => {
user.isModified = true;
return user;
}).do((x) => { console.log('async', x); });
}
const users = [
{ id: 1, name: 'First' },
{ id: 2, name: 'Second' },
{ id: 3, name: 'Third' }
];
Rx.Observable.of(users)
.switchMap((u) => Rx.Observable.forkJoin(u.map(x => asyncOperation(x))))
.subscribe((x) => { console.log('final', x); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.js"></script>
它假定从您的 asyncOperation 返回的可观察对象已完成。它使用 forkJoin
运算符在每个可观察对象全部完成时发出最后一个值。您仍然可以使用 mergeMap
/flatMap
,但我喜欢 switchMap
,因为它只会保留一个对内部可观察对象的订阅。因此,如果源再次发出,那么您将只会得到最新的结果。
此解决方案不需要像使用 toArray
运算符那样完成可观察源 (this.service.find()
)。
关于javascript - 修改可观察列表中的每一项,并再次将修改后的列表作为可观察对象返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47415682/