【问题标题】:RXJS Observables - http call for each index value and merge resultRXJS Observables - 每个索引值和合并结果的 http 调用
【发布时间】:2018-05-26 15:05:08
【问题描述】:

我做了一个 http 调用来获取一个带有 objs 的数组。现在我想为每个返回我 ID 的 objs 调用另一个 http 调用。毕竟我想要一个可观察到的结果。

到目前为止,我设法为每个索引获取了一个 http 调用。我得到了多个问题而不是一个结果。

getStats(tag: string) {
    return this.service.getClanByClanTag(tag)
        .map(clan => {
            return clan.memberList; //the arr that return the ID's
        })
        .switchMap((member: PlayerByMemberListType[]) => {
            return member; // singleObj of the arr
        })
        .concatMap((singleMember) => {
            return this.service.getPlayerData(singleMember.tag).map(player => {
                //push data to the new arr which should return only one time
                this.newArr.push({
                    tag: singleMember.tag,
                    name: singleMember.name,
                    warStars: player.warStars,
                    trophiesNightBase: singleMember.versusTrophies
                });
                return this.newArr;
            });
        });
}

这是控制台在订阅后打印出来的内容:

Array [ {…} ]
Array [ {…}, {…} ]
Array(3) [ {…}, {…}, {…} ]
Array(4) [ {…}, {…}, {…}, {…} ]
Array(5) [ {…}, {…}, {…}, {…}, {…} ]
...

我知道我需要某种Observable.forkJoin,但我不知道如何将它集成到代码中。

【问题讨论】:

  • 尝试使用另一个concatMap 代替地图
  • 与另一个 concatMap 我得到了近 2500 个 objs 而不是 49 个 Objs 的 arr :'D
  • 你在第一张地图上用过吗(.map(clan => { ....)
  • this

标签: javascript angular asynchronous rxjs observable


【解决方案1】:

试试这样的:

this.service.getClanByClanTag(tag)
    .mergeMap(clan => clan.memberList)
    .mergeMap(
        member => this.service.getPlayerData(member.tag), // supposedly this returns an observable
        (member, player) => ({ 
            tag: member.tag,
            name: member.name,
            warStars: player.warStars,
            trophiesNightBase: member.versusTrophies
        })
    )
    .toArray()

【讨论】:

    【解决方案2】:

    所以基本上你想要达到的就是这个。

    1. 获取部落信息
    2. 使用步骤 1 中的氏族信息,在氏族中获取 memberList
    3. 对于memberList 中的每个成员,获取玩家

    您需要想办法在switchMap 之前的step3 中保留step2 的信息。通常我们会使用Subject,但如果你不想使用,只需将mapObservable保存数据即可:

    getStats(tag: string) {
        return this.service.getClanByClanTag(tag)
            .map(clan => {
                return clan.memberList; //the arr that return the ID's
            })
            .switchMap((memberList: PlayerByMemberListType[]) => {
                //note that the following map is a function of javascript array, not Observable
                //it returns an array
                let arrayOfObservables = memberList.map(singleMember => {
                    this.service.getPlayerData(singleMember.tag)
                    //map the data so as to preserve the data of singleMember 
                    //by creating a new object, using Object.assign
                        .map(playerData => {
                            return Object.assign({memberData: singleMember}, playerData,)
                        });
                })
                return Observable.forkJoin(arrayOfObservables);
            })
            .map(players => {
                //players is an array of Object that is the format of {memberData:singleMember, playerData:player)
                //perform Object destructuring method
                return players.map(({memberData,playerData}) => {
                    return {
                        tag: memberData.tag,
                        name: memberData.name,
                        warStars: playerData.warStars,
                        trophiesNightBase: memberData.versusTrophies
                    }
                })
            })
    }
    

    【讨论】:

    • 首先感谢您的方法的详细描述,但 smthng 在这里不起作用,我收到一个错误“您在预期流的位置提供了“未定义”。您可以提供 Observable、Promise、Array 或 Iterable。 arrayOfObservables 将我打印出来:Array(49) [ undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, … ]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    相关资源
    最近更新 更多