代码之家  ›  专栏  ›  技术社区  ›  Chris

角条件HTTP请求内循环

  •  1
  • Chris  · 技术社区  · 8 年前

    我需要能够循环一个对象数组,检查对象的某个属性,如果它是真的,发出一个HTTP请求来获取对象的额外数据。

    目前,我已经把它写成了我脑子里逻辑思考的东西:

    public refreshParticipants(housingTransactionId: string): Observable<Array<Participant>> {
        const url: string = `${config.apiBaseUrl}`;
    
        this.authHttpService.get(url)
            .subscribe(response => {
                let participants = response.json().map(p => Participant.createFromResponse(p));
    
                participants.forEach(participant => {
                    if (participant.isBusinessUser) {
                        this.getParticipantBranchFromHousingTransaction(participant.id, housingTransactionId)
                            .subscribe((branch) => {
                                participant.branchId = branch.id;
                            })
                    }
                    this.participants.push(participant);
                });
    
                return Observable.of(this.participants);
            });
    

    我的问题是请求没有被等待,因此 this.participants 没有人住。

    我不知道怎么写,所以 this.参与者 填充有需要来自HTTP请求的额外数据的参与者和不需要的参与者。

    3 回复  |  直到 8 年前
        1
  •  3
  •   Mark Hughes    8 年前

    一个更简洁的方法来实现你想要做的是使用一个单一的可观测数据来解决整个数据集:

    this.authHttpService.get(url).pipe(
        flatMap((response) => {
            let participants = response.json().map(p => participant.createFromResponse(p));             
            let partDataRequests: Observable<Participant>[] = [];
            participants.forEach((participant) => {
                if (participant.isBusinessUser) {
                    partDataRequests.push(this.getParticipantBranchFromHousingTransaction(participant.id, housingTransactionId).map((branch) => { participant.branchId = branch.id; return participant; });
                } else {
                    partDataRequests.push(of(participant));
                }
            });
            return forkJoin(partDataRequests);
        })
    ).subscribe((enrichedParticipants) => {
        this.participants = enrichedParticipants;
    });
    

    (这是假设rxjs v6,如果使用rxjs v5,语法可能略有不同,但原理相同)

        2
  •  1
  •   Sebastian Münster    8 年前

    问题是,在订阅有响应之前,您的参与者正在被推送。只需将推送线移动到订阅中。 就像

        participants.forEach(participant => {
             if (participant.isBusinessUser) {
                 this.getParticipantBranchFromHousingTransaction(participant.id, housingTransactionId)
                   .subscribe((branch) => {
                      participant.branchId = branch.id;
                      this.participants.push(participant);
                   });
              } else {
                this.participants.push(participant);
              }
        });
    
        3
  •  0
  •   RaidenF    8 年前

    这就是你要找的吗?

        this.authHttpService.get(url)
            .subscribe(response => {
                let participants = response.json().map(p => Participant.createFromResponse(p));
    
                participants.forEach(participant => {
                    if (participant.isBusinessUser) {
                        // perform a request for extra data
                        this.getParticipantBranchFromHousingTransaction(participant.id, housingTransactionId)
                            .subscribe((branch) => {
                                participant.branchId = branch.id;
                                this.participants.push(participant);
                            })
                    }
                    else {
                        // this participant does not require extra data
                        this.participants.push(participant);
                    }
                });
            })
    

    注意数组将被最终确定,而不是在 foreach 循环结束,但当所有请求都得到响应时。