Vueresource等待先前的http请求完成,然后执行下一个请求

问题描述 投票:0回答:1

我试图加载一个大型数据集,并通过小间隔获取数据来分解它

就是这样

假设我有1000条记录,我希望以10的步长获得数据,但只在当前请求完成时请求下一个10

所以目前这正在做什么,但它发出多个http请求,我不知道什么时候一个完成

  processData(){
    this.fetchedtrucks = 0;
    this.dataLoadingCmplete = false;
    this.exportstart = true;
    this.ttatdatatrucks = [];
    let i = 0;
    do {
        const page = (i == 0) ? 0 : (i / (this.paginatorval));
        //send http request

          this.$http.get("v1/data-trucks",
                {
                    from: this.duration_from,
                    to: this.duration_to,
                    page: page,
                    pagination: this.paginatorval,
                    filters: this.filters,
                    only_completed: this.only_completed,
                    non_reg: this.non_reg
                }
            ).then(
                res => {
                    this.ttatdatatrucks = this.ttatdatatrucks.concat(this.getTransformedData(res.ttatdata));
                    this.fetchedtrucks += this.paginatorval;
                    if (this.fetchedtrucks >= this.totalRecords) {
                        this.dataLOadingCompleted();
                    }


                }, err => {
                    this.fetchedtrucks += this.paginatorval;
                    this.errorloadingdata = true;
                }
            )

        i += this.paginatorval;

    } while (i < this.totalRecords);

以上工作,但不是很整齐,因为当我检查浏览器开发工具时,我可以看到超过100个http请求发出我期待做的是仅在当前请求完成时发出下一个http请求

我如何实现这一目标?

vuejs2 vue-resource
1个回答
0
投票

发生这种情况的原因是因为你的do..while循环立即启动了所有的http请求。它并不关心你的承诺,因为它是从外部定义的。

如果不重构大量代码,处理此问题的最简单方法是使用JavaScript async / await关键字。我将演示该解决方案,但如果您无法使用这些运算符,那么我将概述如何重构代码以获得您想要的内容。

首先是简单的方法:你需要使processData异步,这样你就可以在其中放置一个await运算符。您可以通过在processData声明中添加异步关键字来实现这一点 - 如下所示:

async processData() {...

接下来,您需要删除.then包装器并使用await运算符。你在do..while里面的代码看起来像这样:

     try {
            const res = await this.$http.get("v1/data-trucks",
                {
                    from: this.duration_from,
                    to: this.duration_to,
                    page: page,
                    pagination: this.paginatorval,
                    filters: this.filters,
                    only_completed: this.only_completed,
                    non_reg: this.non_reg
                }
            )
            this.ttatdatatrucks = 
            this.ttatdatatrucks.concat(this.getTransformedData(res.ttatdata));
            this.fetchedtrucks += this.paginatorval;
            if (this.fetchedtrucks >= this.totalRecords) {
                this.dataLOadingCompleted();                    
     } catch (err) {
             this.fetchedtrucks += this.paginatorval;
             this.errorloadingdata = true;
     }

此代码将使您的do while循环运行需要很长时间,但它将满足您等待每个http请求完成以执行下一个http请求的要求。

现在,如果await运算符不可用,那么您将需要取消do ... while循环。我认为你不能轻易做到这一点。我将概述你需要做什么。

1)删除do ... while循环

2)将您的i变量和任何其他适当的变量作为参数添加到processData循环中

3)从http请求的.then块递归调用processData()

4)确保为函数添加适当的逻辑以退出递归

看起来有点像这样:

processData(i, complete) {
 if (i >= complete) return;
 this.$http.get()...
 .then(res => {
    //do processing and stuff
    i++
    processData(i, complete)
})

这不是真正的递归,我想 - 这只是一个做...虽然伪装成递归,但它会实现你之后是同步http请求的结果