vue3 请教异步处理方法。我点太快,编号会重复

下而这段代码作用是, 复制表格中的最后一行数据,生成新一行
但是,复制多行时,我连续点击运行这段代码时,
点的速度太快时, 会出现几行相同的编号,慢着点没事
肯定异步造成的,怎么来处理这个异步

 // 复制增加一行,同上一行相同,并改变焦点
    async function addOne (index, row) {
      if(!Number(window.sessionStorage.getItem('allowAdd'))){
        alert('你没有新增数据的权限!')
        return
      }
      // 如果表格中有一行数据就复制
      if(data.searchResult.length>=1){
        const newRow = toRaw(data.searchResult.slice(-1)[0]) // 截取最后一行数据,生成新行
        const newAdd = JSON.parse(JSON.stringify(newRow)) // 深拷贝
        newAdd.id = nanoid()
        //----------------------------------------------------------------
        // 从后端获取 用定自定义的 编号规则
        let numberRules
        const params ={ branch_name: newAdd.branch_name, name: '编号'}
        await getMethod('number_rules/',params).then(res=>{
          numberRules = res[0].rules
        })
        // 获取后端数据库中最后一个编号
        if (numberRules.length>=1){
          let last_number
          await lastId(modData.modelName,newAdd.branch_name).then(res=>{
            last_number =res
          })
          // 用自定义函数,计算出新编号
          const newNumber1 = rulesComput(numberRules,last_number,newAdd)
          // 用当前复制行编号,计算出新编号
          const newNumber2 = rulesComput(numberRules,newAdd.serial_number,newAdd)
          // 比较两个编号,选择最大的为新编号
          if( newNumber1 > newNumber2 ){
            newAdd.serial_number = newNumber1
          }else{
            newAdd.serial_number = newNumber2
          }
        } 
   
        newAdd[modData.editField] = toRaw(newRow[modData.editField] + 1)
        newAdd.showCancel = true
        newAdd.showAddSave = true
        newAdd.showInput= true
        newAdd.is_active = null
        data.searchResult.push(newAdd)
        updateEelement(newAdd.id) // 移动光标位置
      
        // editFocus.value[ data.editField + newAdd.id ].focus()
      
      } else {
        errMessage('页面中最少要有一行数据,才能够复制','提示')
        return
      }
      async function updateEelement(id){
        await nextTick(()=>{
          editFocus.value[ modData.editField+ id ].focus()
        })
      }
      // 改变行数和页数
      page.totalCount = page.totalCount + 1 // 总行数
      page.pageCount = Math.ceil(data.searchResult.length / page.pageSize) // 总页数为当前页
      page.currentPage = page.pageCount // 显示到最后一页
    }

不是异步的问题,你已经是用了async语法糖,里面过程同步执行,只不过你点太快,上一次方法还没执行结束,数据库还没插入新的数据,然后后面点击获取的最后一个编号都是同一个。
解决: 节流函数触发这个新增事件
效果: 无论你怎么点,它都是以一定频率触发函数

如有帮助,麻烦点个[采纳此答案]谢谢^O^

解决办法:从19行到43行 封装成一个函数, 然后把函数在第17行下面调用 ,调用函数时传递返回的numberRules参数即可
问题出现的原因:
由于第17行使用await 关键字,是一个异步操作,js在执行到这行代码时,会将执行加入到微任务队列(不会直接执行)。然后跳过该行,继续向下执行,同步代码执行完才会执行17行的回调。所以重复点击时,由于返回的数据不能同步及时刷新,导致出现某些数据重复。
注意:(同步代码越多,回调延时越长,重复效率越高)
如果有帮助,希望采纳

你代码中没有请求后端接口只是在本地存取数据就不要写成异步了,写成同步执行完美避坑。

建议使用节流函数,或者加个加载动画

你设置个开关,然后点击后判断这个开关是否是开的,如果是你就然后执行请求,如果是关的,你就不执行请求
当你判断是开的时,会进入请求,请求前设置这个开关为关,然后在你的函数最后将这个开关打开即可

已经是用了async语法糖,过程是同步执行的
你点太快,上个方法还没执行结束,数据库还没插入新的数据,然后后面点击获取的最后一个编号都是同一个。
解决: 节流函数触发这个新增事件
效果: 无论你怎么点,它都是以一定频率触发函数

也可以设置个开关,然后点击后判断这个开关是否是开的,如果是你就然后执行请求,如果是关的,你就不执行请求
当你判断是开的时,会进入请求,请求前设置这个开关为关,然后在你的函数最后将这个开关打开即可

可以尝试做个节流 按钮添加一个loading
因为你添加服务器响应可能不及时,就会导致出现问题

再有如果有必要的话每次添加一行,刷新后新添加的表格会不会丢失,如果前端方面可以获取编号生成规则的话可以尝试从前端生成编号

<el-button type="primary" :loading="loading">按钮</el-button>

请求时按钮的loading设为true