2019年02月21日 11:57
原创作品,转载时请务必以超链接形式标明文章原始出处,否则将追究法律责任。

我们在做项目中,经常会遇到这样的场景,一批数据一次扔给API会导致超时,有的用户就喜欢Excel上传,他会在Excel做5000条数据,然后一次上传来完成自己的工作。这种经常导致SqlServer超时报错,http请求超时报错。因此我们需要解决这个问题,怎么解决一种是将数据分批递归,比如5000条,可以分为100批,一批50条调用api完成逻辑。但是这种的话需要自己写递归实现,虽然不难但是建议还是使用第三方js类库。

接下来我们就看一下rxjs库提供的方式,可以保证api的调用是顺序的,回调的结果也是顺序的。

private deleteRecords() {
    const batchCount = 50;
    let loopCount = Math.floor(this.selectedIDs.length / batchCount);
    let loopMod = this.selectedIDs.length % batchCount;
    if (loopMod > 0) {
        loopCount++;
    }

    let deleteSliceArray: Array<Observable<any>> = [];
    for (let i = 0; i < loopCount; i++) {
        let request = {
            IDs: this.selectedIDs
        }

        deleteSliceArray.push(this.maintainService.deleteRecord(request));
    }

    var deleteResponseList: Array<any> = [];

    let deleteObservables = this.concatObservables(deleteSliceArray);
    var runCount = 0;
    deleteObservables.subscribe(response => {
        if (!response) return;

        deleteResponseList = deleteResponseList.concat(response.resultList);
        if (++runCount == loopCount) {
            if (deleteResponseList.find(m => m.IsSuccess)) {
                this.searchHandle(0);
            }

            this.resultDialog.show(deleteResponseList);
        }
    });
}

这是一个删除的例子,用户在UI选择几百条数据进行删除,为了不超时,那么我们只能分批去删除。先计算批次,然后将每批次请求的数据

送入api,在这里我们的访问api返回的是Observable类型

public deleteRecord(request) :Observable<any>{
    return this.apiClient.post(this.deleteUrl,request);
}

因此我们在将所有请求组合进一个集合

let deleteObservables = this.concatObservables(deleteSliceArray);

然后通过订阅获取每次api请求返回的结果。

deleteObservables.subscribe(response => {...});

当请求次数等于我们的批次总数的时候,给用户弹出结果。在这里大家需要注意一下这个concatObservable方法

private concatObservables(list: Observable<any>[]): Observable<any> {
    let concatResult = observableOf(null);

    list.forEach((item) => {
        concatResult = concatResult.pipe(concat(item));
    })

    return concatResult;
}

先声明一个空的Observable,然后将传入的一个个加进去。再通过concat加起来。

发表评论
匿名  
用户评论
暂无评论