详解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 相关文章推荐
javascript 动态调整图片尺寸实现代码
Dec 28 Javascript
基于jquery的使ListNav兼容中文首字拼音排序的实现代码
Jul 10 Javascript
Raphael带文本标签可拖动的图形实现代码
Feb 20 Javascript
点击隐藏页面左栏或右栏实现js代码
Apr 01 Javascript
jquery slibings选取同级其他元素的实现代码
Nov 15 Javascript
详解jQuery中的deferred对象的使用(一)
May 27 Javascript
jquery树形菜单效果的简单实例
Jun 06 Javascript
jqPlot jQuery绘图插件的使用
Jun 18 Javascript
纯js实现的积木(div层)拖动功能示例
Jul 19 Javascript
详解服务端预渲染之Nuxt(介绍篇)
Apr 07 Javascript
微信小程序上传帖子的实例代码(含有文字图片的微信验证)
Jul 11 Javascript
如何在vue中使用video.js播放m3u8格式的视频
Feb 01 Vue.js
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
PHP中使用GD库创建圆形饼图的例子
2014/11/19 PHP
PHP实现过滤掉非汉字字符只保留中文字符
2015/06/04 PHP
php实现源代码加密的方法
2015/07/11 PHP
php实现Session存储到Redis
2015/11/11 PHP
PHP7 mongoDB扩展使用的方法分享
2019/05/02 PHP
jquery 表单下所有元素的隐藏
2009/07/25 Javascript
28个JS验证函数收集
2010/03/02 Javascript
JavaScript类库D
2010/10/24 Javascript
jquery中通过过滤器获取表单元素的实现代码
2011/07/05 Javascript
40个新鲜出炉的jQuery 插件和免费教程[上]
2012/07/24 Javascript
JavaScript创建类/对象的几种方式概述及实例
2013/05/06 Javascript
jquery DIV撑大让滚动条滚到最底部代码
2013/06/06 Javascript
用javascript读取xml文件读取节点数据
2014/08/12 Javascript
一款基jquery超炫的动画导航菜单可响应单击事件
2014/11/02 Javascript
每天一篇javascript学习小结(String对象)
2015/11/18 Javascript
JQuery学习总结【一】
2016/12/01 Javascript
激动人心的 Angular HttpClient的源码解析
2017/07/10 Javascript
bootstrap table实现x-editable的行单元格编辑及解决数据Empty和支持多样式问题
2017/08/10 Javascript
vue 2.0 购物车小球抛物线的示例代码
2018/02/01 Javascript
JS如何操作DOM基于表格动态展示数据
2020/10/15 Javascript
[01:06]DOTA2亚洲邀请赛专属珍藏-荧煌之礼
2017/03/24 DOTA
python 生成目录树及显示文件大小的代码
2009/07/23 Python
python3.5使用tkinter制作记事本
2016/06/20 Python
Python 正则表达式入门(中级篇)
2016/12/07 Python
django使用html模板减少代码代码解析
2017/12/12 Python
详解Numpy中的广播原则/机制
2018/09/20 Python
python ChainMap 合并字典的实现步骤
2019/06/11 Python
python切片(获取一个子列表(数组))详解
2019/08/09 Python
python opencv调用笔记本摄像头
2019/08/28 Python
澳洲最大的时尚奢侈品电商平台:Cettire
2020/06/15 全球购物
房地产销售经理岗位职责
2014/01/01 职场文书
国家税务局领导班子对照检查材料思想汇报
2014/10/04 职场文书
2014年办公室个人工作总结
2014/11/12 职场文书
2014年小学少先队工作总结
2014/12/18 职场文书
证婚人婚礼致辞
2015/07/28 职场文书
搭建zabbix监控以及邮件报警的超级详细教学
2022/07/15 Servers