【问题标题】:Vueresource wait for the previous http request to complete and then perform the next requestvueresource 等待上一个http请求完成再执行下一个请求
【发布时间】:2019-02-11 19:12:26
【问题描述】:

我正在尝试加载一个大型数据集并通过以小间隔获取数据来分解它

原来如此

假设我有 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】:

    发生这种情况的原因是您的 do..while 循环同时启动了所有 http 请求。它与您的承诺无关,因为它是在外部定义的。

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

    首先是简单的方法: 您需要使 processData 异步,以便您可以在其中放置一个 await 运算符。您可以通过在 processData 声明中添加 async 关键字来做到这一点 - 就像这样:

    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 请求完成以执行下一个请求的要求。

    现在,如果 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 请求

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多