详解vue中多个有顺序要求的异步操作处理


Posted in Javascript onOctober 29, 2019

最近项目业务上有个需求,用户可以批量下订单,但每个订单都有一个保价费,手续费需要根据订单的价值由后台的模型算出来,然后下单的时候每个订单都需要带上这个保价费,所以其实在批量下单前,每个订单都需要执行一次后台接口,不要问我为什么不将订单都传给后台,让后台去算,现在的 业务方案是要前端每一个订单都请求一次接口去算出来,然后再批量去下单。

详解vue中多个有顺序要求的异步操作处理

详解vue中多个有顺序要求的异步操作处理

那就写吧,其实就是调用批量下单的接口前,要先每个顶你单调一次查保价费的接口,想着很简单,将保存多选数据的数组遍历,每次执行一次查保价费的接口就好,然后在遍历完后再调用下单接口

代码就这样写吧

`const $this = this

 // 选中多个订单,更新保价费
 // multipleSelection 批量订单的选中数组
 this.multipleSelection.forEach(async(item, index) => {
  console.log('第' + index + '个订单开始查询')
  //将查到的保价费,赋值到insuredValue getComputationCost为查保价费接口
  $this.multipleSelection[index].insuredValue = await getComputationCost({
   value: item.declaredValue,
   goodsTypeCode: item.goodsTypeCode,
  }) || 100
  console.log('第' + index + '个订单查询完成')
 })
 console.log('111', '开始下单')
 const param = {
  orders: this.multipleSelection,
 }
 //批量下单
 const res = await batchAdd(param)
 console.log('222', '下单完成')
 if (res.code === RESPONSE_SUCCESS) {
  this.$message({
   message: '下单成功',
   type: 'success',
  })
 } else {
  this.$message.error(res.msg)
 }`

执行一下,报错了,提示下单接口报错,保价费不能为空,奇怪

看一下打印

详解vue中多个有顺序要求的异步操作处理

查询完保价费之前已经调了下单接口,为什么会这样!

查了一下 async函数会返回一个Promise对象,当函数执行的时候,一旦遇到await关键字就会先返回,其实就是跳出async函数体,等到触发的异步操作完成,再接着执行函数体内后面的语句,而这个async函数返回一个值时,Promise的resolve方法会负责传递这个值;当async函数抛出异常的时候,Promise的reject方法会传递这个异常值

意思是

`$this.multipleSelection[index].insuredValue = await getComputationCost({
   value: item.declaredValue,
   goodsTypeCode: item.goodsTypeCode,
  }) || 100`

await后面的函数不行行,直接执行后面的

所以

`const param = {
  orders: this.multipleSelection,
 }
 const res = await batchAdd(param)`

中传递到 batchAdd函数的param中的multipleSelection的insuredValue是没有值的

也就为什么会提示保价费不能为空

那如果我需要在forEach中的await执行完之后再执行后面的 await那要怎么做呢

来点知识普及:await 返回Promise对象的处理结果,实际就是Promise的回调函数resolve的参数;如果等待的不是Promise对象,则返回值本身

我们都知道Promise是一个立即执行函数,但是他的成功(或失败:reject)的回调函数resolve却是一个异步执行的回调。当执行到resolve()时,这个任务会被放入到回调队列中,等待调用栈有空闲时事件循环再来取走它。

foreach的参数仅仅一个参数回调而foreach本身并不是一个 AsyncFunction 所有foreach循环本身并不能实现await效果。

我将代码这样修改

`// 单个订单查询保价费

asyncFn (item, index) {
 return new Promise(async(resolve, reject) => {
  // console.log('000', '查询保费')
  const res = await getComputationCost({
   value: item.declaredValue,
   goodsTypeCode: item.goodsTypeCode,
  })
  console.log(res, index)
  resolve({
   res: res,
   index: index,
  })
 })
},
async setOrder() {
 if (this.multipleSelection.length === 0) {
  return this.$message.error('请先选择要下单的订单')
 }
 const array = []
 const $this = this
 // 选中多个订单,更新保价费
 this.multipleSelection.forEach((item, index) => {
  array.push(this.asyncFn(item, index).then(res => {
   // console.log(index, res)
   $this.multipleSelection[index].insuredValue = res.data || 100
  }))
 })
 Promise.all(array).then(async(result) => {
  // console.log('all', result)
  // console.log('666', '开始下单')
  const param = {
   orders: this.multipleSelection,
  }
  const res = await batchAdd(param)
  // console.log('下单完成', res)
  if (res.code === RESPONSE_SUCCESS) {
   this.$message({
    message: '下单成功',
    type: 'success',
   })
  } else {
   this.$message.error(res.msg)
  }
 })
},`

执行一下,提示下单成功

看一下打印

详解vue中多个有顺序要求的异步操作处理

是我想要的效果了

原理就是通过一个promise函数,将每一次请求保价费的请求放到一个数组里,通过promise.all,去处理,然后在这个promise对面的resolve里面去执行批量下单的操作。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery.jstree 增加节点的双击事件代码
Jul 27 Javascript
jquery实现心算练习代码
Dec 06 Javascript
将Datatable转化成json发送前台实现思路
Sep 06 Javascript
如何解决Jquery库及其他库之间的$命名冲突
Sep 15 Javascript
jquery中邮箱地址 URL网站地址正则验证实例代码
Sep 15 Javascript
使用phantomjs进行网页抓取的实现代码
Sep 29 Javascript
深入分析jquery解析json数据
Dec 09 Javascript
JavaScript模拟鼠标右键菜单效果
Dec 08 Javascript
socket.io学习教程之深入学习篇(三)
Apr 29 Javascript
解决webpack无法通过IP地址访问localhost的问题
Feb 22 Javascript
jquery 给动态生成的标签绑定事件的几种方法总结
Feb 24 jQuery
Vue项目前后端联调(使用proxyTable实现跨域方式)
Jul 18 Javascript
vue实现设置载入动画和初始化页面动画效果
Oct 28 #Javascript
vue设置一开始进入的页面教程
Oct 28 #Javascript
Vue调用后端java接口的实例代码
Oct 28 #Javascript
原生js实现商品筛选功能
Oct 28 #Javascript
使用Vue实现调用接口加载页面初始数据
Oct 28 #Javascript
JavaScript制作3D旋转相册
Aug 02 #Javascript
微信小程序工具函数封装
Oct 28 #Javascript
You might like
vBulletin HACK----关于排版的两个HACK
2006/10/09 PHP
基于PHP字符串的比较函数strcmp()与strcasecmp()的使用详解
2013/05/15 PHP
ThinkPHP中使用Ueditor富文本编辑器
2015/09/02 PHP
针对多用户实现头像上传功能PHP代码 适用于登陆页面制作
2016/08/17 PHP
CodeIgniter开发实现支付宝接口调用的方法示例
2016/11/14 PHP
详解PHP如何更好的利用PHPstorm的自动提示
2017/08/18 PHP
JS 文件大小判断的实现代码
2010/04/07 Javascript
JS判断指定dom元素是否在屏幕内的方法实例
2017/01/23 Javascript
利用node实现一个批量重命名文件的函数
2017/12/21 Javascript
在vue里面设置全局变量或数据的方法
2018/03/09 Javascript
详解webpack打包时排除其中一个css、js文件或单独打包一个css、js文件(两种方法)
2018/10/26 Javascript
Vue动态组件与异步组件实例详解
2019/02/23 Javascript
vue.js中ref和$refs的使用及示例讲解
2019/08/14 Javascript
python基于phantomjs实现导入图片
2016/05/13 Python
修复CentOS7升级Python到3.6版本后yum不能正确使用的解决方法
2018/01/26 Python
Django中自定义查询对象的具体使用
2019/10/13 Python
pytorch 实现在一个优化器中设置多个网络参数的例子
2020/02/20 Python
几款好用的python工具库(小结)
2020/10/20 Python
美国非常受欢迎的Spa品牌:Bliss必列斯
2018/04/10 全球购物
节省高达65%的城市景点费用:Go City
2019/07/06 全球购物
求职简历中自我评价
2014/01/28 职场文书
《小蝌蚪找妈妈》教学反思
2014/02/21 职场文书
改革共识倡议书
2014/08/29 职场文书
领导班子个人对照检查材料(群众路线)
2014/09/26 职场文书
科技活动周标语
2014/10/08 职场文书
2014最新自愿离婚协议书范本
2014/11/19 职场文书
2014年班级工作总结范文
2014/12/23 职场文书
2015年人力资源工作总结
2015/04/08 职场文书
2015年高中班主任工作总结
2015/04/30 职场文书
汤姆索亚历险记读书笔记
2015/06/29 职场文书
母婴行业实体、电商模式全面解析
2019/08/01 职场文书
教你用python控制安卓手机
2021/05/13 Python
MySQL 数据类型选择原则
2021/05/27 MySQL
教你使用pyinstaller打包Python教程
2021/05/27 Python
postgresql 删除重复数据案例详解
2021/08/02 PostgreSQL
Win11 25163.1010更新补丁KB5016904推送,测试服务验证管道(附更新修复汇总)
2022/07/23 数码科技