且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

展平嵌套的 Observable

更新时间:2022-10-19 15:14:52

实际上,您不需要 forkJoin()switch() 来执行此操作.

通常,您希望通过另一个异步调用更新用户数组中的每个用户.

我会这样做:

var source = findUser('term').mergeAll().mergeMap(user => getLastLogin(user.user_id).map(last_login => {user.last_login = last_login;返回用户;})).toArray();source.subscribe(val => console.log(val));

运算符 mergeAll() 将高阶 Observable 转换为单个 Observable.在这种情况下,它获取所有用户的数组并一个一个地重新发送它们.然后 mergeMap() 发出更新了 last_login 日期的用户.最后,我使用 toArray() 将单个用户转换为一个大数组,将它们作为整体发出(如果您想发出单个用户,则可以删除此运算符).

请注意,当您使用 return users.map(...) 时,您使用的是 Array.map() 返回一个数组而不是 map() 来自返回 Observable 的 RxJS.我认为使用单个对象通常比使用对象数组更容易.

查看现场演示:https://jsbin.com/naqudun/edit?js,console

这会打印到控制台:

[ { name: 'foo',用户 ID:42,last_login: 2016-11-06T10:28:29.314Z },{名称:'酒吧',用户 ID:21,最后登录:2016-11-06T10:28:29.316Z }]

I'm a stuck in nested observable hell and could do with a hand.

I have the following block of code

return this.findUser(term).map( users => {
  return users.map( user => this.getLastLogin(user.user_id).map( last_login => {
    user.last_login = last_login;
    return user;
  }));
});

findUser returns Observable<User[]> and getLastLogin returns Observable<number>.

I'm basically hoping to fetch a list of users and then update this with the information from another value.

Right now the code above is returning <Observable<Observable<User>[]>.

I thought I could replace the initial map with flatMap but this turns the object into <Observable<Observable<User>>.

The RxJS documentation is a little hard to decipher so I'm not sure what combination of switch, forkJoin or flatMap will get me to what I need.

I'm hoping to return Observable<User[]>. Could anyone point me in the right direction?

Actually, you don't need forkJoin() nor switch() to do this.

In general, you want to update each user in the array of users by another async call.

I'd do it like this:

var source = findUser('term')
    .mergeAll()
    .mergeMap(user => getLastLogin(user.user_id)
        .map(last_login => {
            user.last_login = last_login;
            return user;
        })
    )
    .toArray();

source.subscribe(val => console.log(val));

Operator mergeAll() converts a higher-order Observable into single observables. In this case it takes the array of all users and re-emits them one by one. Then mergeMap() emits users updated with the last_login date. At the end I used toArray() to transform single users into one large array that is them emitted as whole (you can remove this operator if you want to emit single users instead).

Note that when you used return users.map(...) you were using Array.map() that returns an array and not map() from RxJS that returns an Observable. I think working with single objects is usually easier that with arrays of objects.

See live demo: https://jsbin.com/naqudun/edit?js,console

This prints to console:

[ { name: 'foo',
    user_id: 42,
    last_login: 2016-11-06T10:28:29.314Z },
  { name: 'bar',
    user_id: 21,
    last_login: 2016-11-06T10:28:29.316Z } ]