目录

一、干了什么?

二、问题及解决方案

2.1 出现问题:axios循环发送请求并没有按顺序执行

2.1.1 错误代码

2.1.2 代码实现逻辑

2.1.3  出错信息

2.2 解决过程分析

2.2.1 错误部分

2.2.2 解决await在forEach不起作用

2.2.3 解决方法内axios通信顺序问题

2.3 效果展示

总结


一、干了什么?

2022/6/3 系统出现了一个bug,在新建实体表时出现了问题。发现新建的表字段数不够。

新建表的字段是从元信息表中获取的。

证明是元信息表还没有创建完成,系统就已经调用这些元信息开始创建实际的表了。

分析分析,发现还是axios异步通信的问题!!!

简单介绍一下错在哪里和怎么解决吧,希望以后开发过程中能够避开~~

二、问题及解决方案

2.1 出现问题:axios循环发送请求并没有按顺序执行

2.1.1 错误代码

click3(){
        //这里就直接复制粘贴即可
        this.submitForm3();
        this.dialogVisible=true
      },
submitForm3() {
       this.columnList.forEach((item,index) => {
         let params = new URLSearchParams()
         params.append('DBid',this.dbid)
         params.append('CHARTid',this.chartid)
         params.append('MEN',this.columnList[index])
         params.append('Types',this.aboutColumns.types[index])
         params.append('ZDes',this.aboutColumns.ZDescrs[index])
         params.append('ZN',this.aboutColumns.ZNames[index])
         axios.post(`api/insertMeta`,params).then(res=>{
           console.log('表的详细信息第 '+index+' 列已经发出去了')
           console.log(res.data)
         })
      });

        //创建实体表
      let params1 = new URLSearchParams()
      params1.append('DBid',this.dbid)
      params1.append('CHARTid',this.chartid)
      params1.append('EN',this.biaoF.Ename)
      axios.post(`api/createUTable`,params1).then(res=>{
         console.log('已发出实体表相关信息')
         console.log(res.data)
         })
       
    },

2.1.2 代码实现逻辑

1.点击按钮

调用submitForm3()方法

2.submitForm3()方法逻辑:

step1:使用forEach循环使用axios向后端传递新建表meta信息,后端在元信息表中插入该条信息;

step2:step1完成之后,使用axios像后端传递新建表信息,并创建表。

3.创建表的后端逻辑

利用2中step2传过来的dbid,chartid,EN,找到要新建表的元信息表,使用map存储元信息,利用map使用JDBC语句创建表,表名为EN。

2.1.3  出错信息

根据控制台输出

console.log('表的详细信息第 '+index+' 列已经发出去了')

  发现发出去的列并不是按顺序的,而是随机的,顺序是3,0,1,2也可能是1,2,3,0。

总之顺序完全随机。

根据后端输出1

//controller层
 System.out.println(DBid+"----------------------"+
CHARTid+"----------------------"+MEN+"----------------------");
        System.out.println(Types+"----------------------"+
ZDes+"----------------------"+ZN+"----------------------");

        int dbid = Integer.parseInt(DBid);
        int chartid = Integer.parseInt(CHARTid);
        System.out.println("把传过来的dbid转为int:"+dbid+"
把传过来的chartid转为int:"+chartid);

//service层
System.out.println("插入数据到"+metaName+"表中成功与否:"+ insertMeta );

  发现后端接受前端meta信息时,也不是顺序执行的,可能在一条meta信息还没有插入到元信息表中,另一条信息就从前端传过来了。

控制台输出完全是混乱的。

根据后端输出2

//controller层
String DBid =req.getParameter("DBid").trim();
String Chartid =req.getParameter("CHARTid").trim();
String CName =req.getParameter("EN").trim();
//首先获取DBid 和 CHARTid
System.out.println(DBid+"----------------------"+Chartid+"
----------------------");


//service层
 System.out.println("到这一步");

  再加上在传输完meta列表之后,会调用创建实体表方法createUTable()axios异步通信同样导致了可能meta列表传完了,但是后端还没有实现所有meta信息都插入元信息表中时,就调用创建表方法,导致创建表为空(出错)、创建表字段不够 、创建表字段顺序不对等问题。

2.2 解决过程分析

2.2.1 错误部分

已经发现是axios异步通信的错误,只要让代码按照逻辑顺序执行就好了。

所以刚开始就想要直接使用async/await直接使用。这个怎么用之前讲过。有需要可以看看axios通信导致vue前端数据不一致。

修改后代码如下

async click3(){
        //这里就直接复制粘贴即可
        await this.submitForm3();
        this.dialogVisible=true
      },
async submitForm3() {
       this.columnList.forEach((item,index) => {
         let params = new URLSearchParams()
         params.append('DBid',this.dbid)
         params.append('CHARTid',this.chartid)
         params.append('MEN',this.columnList[index])
         params.append('Types',this.aboutColumns.types[index])
         params.append('ZDes',this.aboutColumns.ZDescrs[index])
         params.append('ZN',this.aboutColumns.ZNames[index])
         await axios.post(`api/insertMeta`,params).then(res=>{
           console.log('表的详细信息第 '+index+' 列已经发出去了')
           console.log(res.data)
         })
      });

        //创建实体表
      let params1 = new URLSearchParams()
      params1.append('DBid',this.dbid)
      params1.append('CHARTid',this.chartid)
      params1.append('EN',this.biaoF.Ename)
      await axios.post(`api/createUTable`,params1).then(res=>{
         console.log('已发出实体表相关信息')
         console.log(res.data)
         })
       
    },

结果发现报错:

await is a reserved word

怎么回事呢?——原来是await在forEach不起作用!

具体分析,请移步如何在 JS 循环中正确使用 async 与 await

2.2.2 解决await在forEach不起作用

await在forEach循环中不起作用,将forEach改为for循环即可

改前:

this.columnList.forEach((item,index) => {
         let params = new URLSearchParams()
         params.append('DBid',this.dbid)
         params.append('CHARTid',this.chartid)
         params.append('MEN',this.columnList[index])
         params.append('Types',this.aboutColumns.types[index])
         params.append('ZDes',this.aboutColumns.ZDescrs[index])
         params.append('ZN',this.aboutColumns.ZNames[index])
         await axios.post(`api/insertMeta`,params).then(res=>{
           console.log('表的详细信息第 '+index+' 列已经发出去了')
           console.log(res.data)
         })
      });

改后:

for(let index = 0;index < this.columnList.length;index++){
let params = new URLSearchParams()
         params.append('DBid',this.dbid)
         params.append('CHARTid',this.chartid)
         params.append('MEN',this.columnList[index])
         params.append('Types',this.aboutColumns.types[index])
         params.append('ZDes',this.aboutColumns.ZDescrs[index])
         params.append('ZN',this.aboutColumns.ZNames[index])
         console.log("MEN:"+this.columnList[index]+"__"+"Types:"
+this.aboutColumns.types[index]
+"__"+"ZDes:"+this.aboutColumns.ZDescrs[index]+"__"+"ZN:"
+this.aboutColumns.ZNames[index]);
         await axios.post(`api/insertMeta`,params).then(res=>{
           console.log(params)
           console.log('表的详细信息第 '+index+' 列已经发出去了')
           console.log(res.data)
         })
             
           }

  这样就解决了前端发送执行的问题,但是在进行发送完成之后,会调用createUTable()方法,同样也是利用axios异步通信。这样仍然可能导致在最后一个meta信息还没有插入元信息表时,就已经创建了实体表。

2.2.3 解决方法内axios通信顺序问题

因为要等所有的meta信息插入元信息表,再创建实体表。所以这里:

step1:直接在click3中,创建两个新方法:

    方法一submitForm3():把所有的meta信息插入元信息表。

    方法二createUTable():创建实体表。

step2:使用async/await,使这两个方法顺序执行

就可以解决啦!

具体实现代码如下

async click3(){
        //这里就直接复制粘贴即可
        await this.submitForm3();
         //创建实体表
        await this.createUTable();

        this.dialogVisible=true
      },
async submitForm3() {
      for(let index = 0;index < this.columnList.length;index++){
        await this.insertMeta(index);
      }
       
     },
async insertMeta(index){
      let params = new URLSearchParams()
         params.append('DBid',this.dbid)
         params.append('CHARTid',this.chartid)
         params.append('MEN',this.columnList[index])
         params.append('Types',this.aboutColumns.types[index])
         params.append('ZDes',this.aboutColumns.ZDescrs[index])
         params.append('ZN',this.aboutColumns.ZNames[index])
         console.log("MEN:"+this.columnList[index]+"__"+"Types:"
+this.aboutColumns.types[index]+"__"+"ZDes:"
+this.aboutColumns.ZDescrs[index]+"__"+"ZN:"
+this.aboutColumns.ZNames[index]);
         await axios.post(`api/insertMeta`,params).then(res=>{
           console.log(params)
           console.log('表的详细信息第 '+index+' 列已经发出去了')
           console.log(res.data)
         })

     },
async createUTable(){
      let params1 = new URLSearchParams()
      params1.append('DBid',this.dbid)
      params1.append('CHARTid',this.chartid)
      params1.append('EN',this.biaoF.Ename)
      await axios.post(`api/createUTable`,params1).then(res=>{
         console.log('已发出实体表相关信息')
         console.log(res.data)
         })
     },

这样就简单明了很多,也方便找错误。

2.3 效果展示

前端顺序发送:

axios 多个顺序请求 如何解决axios执行顺序_spring boot

后端顺序执行:

axios 多个顺序请求 如何解决axios执行顺序_后端_02

axios 多个顺序请求 如何解决axios执行顺序_ios_03

数据库中创建的表:

元信息表:

axios 多个顺序请求 如何解决axios执行顺序_后端_04

 实体表:

axios 多个顺序请求 如何解决axios执行顺序_axios 多个顺序请求_05


总结

主要还是axios通信的问题,以及实现顺序执行时使用async/await的一些限制。