详解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 相关文章推荐
MooTools 1.2中的Drag.Move来实现拖放
Sep 15 Javascript
JavaScript 学习笔记(十一)
Jan 19 Javascript
精选的10款用于构建良好易用性网站的jQuery插件
Jan 23 Javascript
jQuery Jcrop插件实现图片选取功能
Nov 23 Javascript
jquery获取子节点和父节点的示例代码
Sep 10 Javascript
jquery插件开发之实现jquery手风琴功能分享
Mar 10 Javascript
js获取时间精确到秒(年月日)
Mar 16 Javascript
JavaScript遍历求解数独问题的主要思路小结
Jun 12 Javascript
学习Angular中作用域需要注意的坑
Aug 17 Javascript
JavaWeb表单及时验证功能在输入后立即验证(含用户类型,性别,爱好...的验证)
Jun 09 Javascript
jQuery dateRangePicker插件使用方法详解
Jul 28 jQuery
利用JavaScript实现栈的数据结构示例代码
Aug 02 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
模仿OSO的论坛(五)
2006/10/09 PHP
关于PHP实现异步操作的研究
2013/02/03 PHP
PHP Class&Object -- 解析PHP实现二叉树
2013/06/25 PHP
PHP通过加锁实现并发情况下抢码功能
2016/08/10 PHP
thinkPHP引入类的方法详解
2016/12/08 PHP
完美解决Thinkphp3.2中插入相同数据的问题
2017/08/01 PHP
使javascript也能包含文件
2006/10/26 Javascript
javascript脚本编程解决考试分数统计问题
2008/10/18 Javascript
使用jQuery异步加载 JavaScript脚本解决方案
2014/04/20 Javascript
js实现键盘操作实现div的移动或改变的原理及代码
2014/06/23 Javascript
浅析node.js中close事件
2014/11/26 Javascript
jquery制作 随机弹跳的小球特效
2015/02/01 Javascript
jquery实现可横向和竖向展开的动态下滑菜单效果
2015/08/24 Javascript
通过Ajax使用FormData对象无刷新上传文件方法
2016/12/08 Javascript
vue父组件触发事件改变子组件的值的方法实例详解
2019/05/07 Javascript
[04:21]狐狸妈带你到现场 DOTA2 TI中国区预选赛线下赛路线指引
2014/05/22 DOTA
[50:02]完美世界DOTA2联赛PWL S2 Magma vs FTD 第三场 11.29
2020/12/03 DOTA
跟老齐学Python之集成开发环境(IDE)
2014/09/12 Python
python自动化测试之连接几组测试包实例
2014/09/28 Python
python实现人民币大写转换
2018/06/20 Python
Python实现购物评论文本情感分析操作【基于中文文本挖掘库snownlp】
2018/08/07 Python
python pandas实现excel转为html格式的方法
2018/10/23 Python
PyQT5 QTableView显示绑定数据的实例详解
2019/06/25 Python
Python configparser模块配置文件过程解析
2020/03/03 Python
什么是python的函数体
2020/06/19 Python
详解基于Scrapy的IP代理池搭建
2020/09/29 Python
梅西百货澳大利亚:Macy’s Australia
2017/07/26 全球购物
来自美国主售篮球鞋的零售商店:KICKSUSA
2017/11/28 全球购物
运动服饰每月订阅盒:Ellie
2018/04/29 全球购物
Nisbets爱尔兰:英国最大的厨房和餐饮设备供应商
2019/01/26 全球购物
C#怎么让一个窗口居中显示?
2015/10/20 面试题
大学优秀班主任事迹材料
2014/05/02 职场文书
大学生受助感言
2015/08/01 职场文书
员工安全责任协议书
2016/03/22 职场文书
原来闭幕词是这样写的呀!
2019/07/01 职场文书
go语言中http超时引发的事故解决
2021/06/02 Golang