栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

分批导入功能——按顺序循环执行异步请求(使用递归)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

分批导入功能——按顺序循环执行异步请求(使用递归)

工作中遇到的一个需求完成过程:
某页面导入数据超过50条会卡顿,然后产品经理让我限制成只允许导入50条以内的数据,否则报错。
改完发版到正式环境后,用户觉得要把文档拆分成好几个太麻烦了,比如要导入300多条数据,就要把原excel文件拆成7个再一份一份导入,用户体验很差。
于是这次迭代让我解除只允许导入50条的限制,想办法给导入加个进度条,让用户在等待的冗长时间里能感受到导入正在进行。

但是问题来了,导入是调的后端接口,只有在开始执行时进入pending状态,然后一直pending到请求成功或失败后才会返回结果,所以做成进度条是不现实的(除非是像浏览器那种永远读不完的加载条,但这样单纯是为了提高用户体验而毫无意义)。

那么该如何更好的完成这次需求呢?既然导入时不超过50条就不会特别卡顿,那么在导入超过50条数据时,我们做成分批导入,每50条数据调用一次接口,并在请求成功或失败时提示用户【第n到第n+50条数据导入成功/失败】,就能更好的完成原定需求并提升用户体验度。


如果后端同事愿意配合,可以让他帮忙先写个导入前的数据校验接口,例如导入200条数据前先校验这200条数据填写的格式是否都正确,不然直接导入了请求执行到一半,花了很久时间却因为表格填写有误结果导入失败了,用户应该也会抱怨(推锅)的吧。
不过校验这种事前端也能写,根据项目分配来决定吧。


回到正题:想要完成上述的操作,即在不知道要传入的数据有多大的情况下,按顺序分批次导入,就得在执行完50条批量导入请求前不能插入下一个批量导入请求,否则导入的数据会乱套。
但是请求是异步的,我们要解决的就是将循环导入的异步请求按顺序去执行。用for + index的方法去循环执行是避免不了请求异步的,所以写成递归来执行请求,既能实现需求也比其他方法要来得方便。

    // 递归分批导入仪表
    recursionMeterImport(arr, index, otherArr, otherIndex) {
      // arr为分批导入的数据数组,index是递归时导入的第几批数组。otherArr是执行完当前递归后再执行的下一种类导入数据的数组,otherIndex同上。
      // 最开始先判断arr是否为空,不为空则执行导入请求,为空则开始进行下一种类的数据导入 
      if (arr.length) {
        this.importInfo +=
          "n" +
          `正在导入第${index * 50 + 1}条至第${(index + 1) * 50}条数据...`;
        ajax.post("xxxx(批量导入接口)", arr[index])
          .then((res) => {
            this.importInfo += "n" + res.data.message;  // 后端返回的提示信息,【XX条数据导入成功】
            if (res.data.body && res.data.body.length > 0) {
              res.data.body.forEach((item, i) => {
                this.importInfo += "n" + `【${index * 50 + i + 1}】:` + item; // 批量导入时每天数据的导入返回提示信息
              });
            }
            if (arr.length > index + 1) {
              // 导入的不是最后一批数据,递归执行导入下一批数据
              this.recursionMeterImport(arr, index + 1, otherArr, otherIndex);
            } else {
              // 导入完数组的最后一批数据后,执行下一种类数据的递归导入
              this.importInfo +=
                "n" + this.lang.ImportingMeterGroupStandardValue + "..."; // 提示开始导入下一种类数据
              this.recursionMetergroupImport(otherArr, otherIndex);
            }
          })
          .catch(() => {
            this.$alert(
              "网络波动原因或未知错误导致导入失败,请重试或联系系统管理员!",
              this.lang.Tips
            );
            this.btnDisabled = false;
          });
      } else {
        this.importInfo += "n" + "仪表导入对标值内容为空";
        this.importInfo +=
          "n" + this.lang.ImportingMeterGroupStandardValue + "...";
        this.recursionMetergroupImport(otherArr, otherIndex);
      }
    },

	// 递归分批导入仪表分组
    recursionMetergroupImport(arr, index) {
      // 下一种类的递归导入,基本同上,不再赘述
      if (arr.length) {
        this.importInfo +=
          "n" +
          `正在导入第${index * 50 + 1}条至第${(index + 1) * 50}条数据...`;
        ajax.post("xxxx(下一种类批量导入接口)", arr[index])
          .then((res) => {
            this.importInfo += "n" + res.data.message;
            if (res.data.body && res.data.body.length > 0) {
              res.data.body.forEach((item, i) => {
                this.importInfo += "n" + `【${index * 50 + i + 1}】:` + item;
              });
            }
            if (arr.length > index + 1) {
              // 导入的不是最后一批数据,继续执行递归
              this.recursionMetergroupImport(arr, index + 1);
            } else {
              this.importInfo += "n" + "对标值已全部导入成功!";
              this.$alert("对标值已全部导入成功!", this.lang.Tips);
              this.search();
              this.btnDisabled = false;
            }
          })
          .catch(() => {
            this.$alert(
              "网络波动原因或未知错误导致导入失败,请重试或联系系统管理员!",
              this.lang.Tips
            );
            this.btnDisabled = false;
          });
      } else {
        this.importInfo += "n" + "仪表分组导入对标值内容为空";
        this.importInfo += "n" + "对标值已全部导入成功!";
        this.$alert("对标值已全部导入成功!", this.lang.Tips);
        this.search();
        this.btnDisabled = false;
      }
    },

数组切割的方法请见我上一篇文章:JS将一个数组切割成同等大小的多个数组的方法


小记:刚听到一个不合理的需求时先不要急,和产品经理说明不合理的地方并提供自己的想法,有时他会觉得你的方案更好并采用,在动手完成的过程中跟着自己的思路走就能迎刃而解,事半功倍。
THX~

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1010157.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号