首页 > 解决方案 > Angular 6 RxJS6 observable 未按正确顺序返回数据

问题描述

我正在遍历一个数组并调用LoadReportsData. getProjectReportsDatain以正确的_reportingService 顺序被调用。但是当控件从服务映射返回时被命中,然后.subscribe()内部的代码直到所有调用都被命中。

之后,结果被分配给this.reportData但随机顺序。由于这种行为,我在工作簿中的工作表是随机创建的,而不是按预期顺序创建的。请建议是否有其他拨打电话的方式和/或建议一些解决方法。

FetchProjectSubmissionReportingAssets(ID: number,
        mySelectiontot: number, PRsDelimitedList: string, StartDate: string, EndDate: string) {

        let currAsset: string = '';
        let ID: number;
        var fetchAssetData = {
            'CSID': ID
        }
        this._reportingService.isLoading = true;
        this._reportingService.getProjSubRptAssets(fetchAssetData).pipe(
            map(result => {
                if (result != null) {

                    for (var i = 0; i < result.length; i++) {
                        this.ProjReqSubmissionReportingAssets = result;


                        currAsset = result[i].option;
                        ID = result[i].id;

                        this.LoadReportsData(ID, currAsset, i);

                    }
                }
            }))
            .subscribe();


    }


    LoadReportsData(CSAsID: number, currAsset: string, tabIndex: number) {

        this.wb = XLSX.utils.book_new();

            var indata = {
                'CSID': this.CSID,
                'CSAsID': CSAsID,
                'StartDate': this.StartDate,
                'EndDate': this.EndDate,
                'PRsDelimitedList': this.PRsDelimitedList

            }
            this._reportingService.getProjectReportsData(indata).pipe(
                map(result => {

                        this.reportData = result;

                        this.idx = this.idx + 1;

                        if (this.reportData != null) {
                            this.ws = this.ws + '_' + tabIndex.toString();
                            this.ws = XLSX.utils.json_to_sheet(this.reportData);
                            XLSX.utils.book_append_sheet(this.wb, this.ws, currAsset);
                            console.log(currAsset);
                        }
                        if (this.ProjReqSubmissionReportingAssets.length == this.idx) {
                            var currDateTime = this.fn_getTimeStamp();
                            XLSX.writeFile(this.wb, "ProjReport_" + this.HCs + "_" + currDateTime + ".xlsx");
                        }

                }))
            .subscribe();

            this._reportingService.isLoading = false;

}

标签: angulartypescriptobservablerxjs6

解决方案


您可以创建一个包含所有 API 调用的数组,而不是在循环中进行 API 调用combineLatest。然后订阅者最终会以正确的顺序接收数据。

一般来说,是这样的:

    this._reportingService.getProjSubRptAssets(fetchAssetData).pipe(
        filter(result => result !== null),
        map(result => result.map(
            curAsset => this.LoadReportsData(curAsset.id, curAsset, i)
        )),
        switchMap(requestsArray => combineLatest(requestsArray))
    ).subscribe(
        resultArray => {
            // resultArray should consist responses of API calls in the same order
            // the results getProjSubRptAssets(fetchAssetData) came in
        })

推荐阅读