详解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 相关文章推荐
JS 表单验证大全
Nov 23 Javascript
js单例模式的两种方案
Oct 22 Javascript
javascript删除option选项的多种方法总结
Nov 22 Javascript
jQuery设置与获取HTML,文本和值的简单实例
Feb 26 Javascript
JavaScript静态类型检查工具FLOW简介
Jan 06 Javascript
Jquery实现动态切换图片的方法
May 18 Javascript
jquery实现先淡出再折叠收起的动画效果
Aug 07 Javascript
javascript+HTML5自定义元素播放焦点图动画
Feb 21 Javascript
WordPress 单页面上一页下一页的实现方法【附代码】
Mar 10 Javascript
jQuery模拟窗口抖动效果
Mar 15 Javascript
JavaScript实现获取用户单击body中所有A标签内容的方法
Jun 05 Javascript
Vue的MVVM实现方法
Aug 16 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
PHP默认安装产生系统漏洞
2006/10/09 PHP
《PHP编程最快明白》第七讲:php图片验证码与缩略图
2010/11/01 PHP
PHP扩展模块Pecl、Pear以及Perl的区别
2014/04/09 PHP
PHP+MySQL插入操作实例
2015/01/21 PHP
php实现TCP端口检测的方法
2015/04/01 PHP
利用php-cli和任务计划实现刷新token功能的方法
2017/05/03 PHP
Javascript 日期对象Date扩展方法
2009/05/30 Javascript
JavaScript 继承详解(四)
2009/07/13 Javascript
jQuery对象[0]是什么含义?
2010/07/31 Javascript
js对象的比较
2011/02/26 Javascript
JavaScript之自定义类型
2012/05/04 Javascript
ajax页面无刷新 IE下遭遇Ajax缓存导致数据不更新的问题
2012/12/11 Javascript
js中回调函数的学习笔记
2014/07/31 Javascript
谈谈JavaScript中function多重理解
2015/08/28 Javascript
jQuery+css实现的换页标签栏效果
2016/01/27 Javascript
JavaScript模版引擎的基本实现方法浅析
2016/02/15 Javascript
利用JQuery写一个简单的异步分页插件
2016/03/07 Javascript
nodemon实现Typescript项目热更新的示例代码
2019/11/19 Javascript
vue自动添加浏览器兼容前后缀操作
2020/08/13 Javascript
jQuery列表动态增加和删除的实现方法
2020/11/05 jQuery
Python制作钉钉加密/解密工具
2016/12/07 Python
Python:Scrapy框架中Item Pipeline组件使用详解
2017/12/27 Python
微信跳一跳python辅助脚本(总结)
2018/01/11 Python
Python 保存矩阵为Excel的实现方法
2019/01/28 Python
安装完Python包然后找不到模块的解决步骤
2020/02/13 Python
Python要如何实现列表排序的几种方法
2020/02/21 Python
Python3.7在anaconda里面使用IDLE编译器的步骤详解
2020/04/29 Python
大学生求职自荐信
2013/12/12 职场文书
廉洁使者实施方案
2014/03/29 职场文书
贷款委托书
2014/08/01 职场文书
2015年打非治违工作总结
2015/04/02 职场文书
离婚被告答辩状
2015/05/22 职场文书
鲁冰花观后感
2015/06/10 职场文书
房贷收入证明范本
2015/06/12 职场文书
红歌会主持词
2015/07/02 职场文书
一次Mysql update sql不当引起的生产故障记录
2022/04/01 MySQL