网站建设 好的公司,甘肃建设体网站,wordpress 商城模版,太极馆如何做网站微信小程序多图片上传实用代码记录 
由于在小程序中#xff0c;wx.uploadFile 只能一次上传一张图片#xff0c;因此在一次需要上传多张图片的应用场景中例如商品图片上传、评论图片上传等场景下#xff0c;不得不使用for等循环上传每一张图片#xff0c;多次调用wx.upload…微信小程序多图片上传实用代码记录 
由于在小程序中wx.uploadFile 只能一次上传一张图片因此在一次需要上传多张图片的应用场景中例如商品图片上传、评论图片上传等场景下不得不使用for等循环上传每一张图片多次调用wx.uploadFile由此引发了ajax的闭包问题。 
初始代码 
submit() {let tmparr  null;let _that  this;for (var k  0; k  this.data.judgedetaillist.length; k) {let _k  k;//图片上传this.data.fileList[_k].forEach((item)  { wx.uploadFile({   //这里一定要用  wx.uploadFile 否则无法穿到后台filePath: item.url, //你要上传的路径name: file,   //你上传到后台的name值async: false, //设置为同步formData:{    // 如果你要验证你的token 可以用formData来给后台传值path:judge},url: 上传地址,success(res){let img  JSON.parse(res.data); //录入到listif(img.errsuccess  img.c_url!null  img.c_url!undefined){if(_that.data.judgedetaillist[_k].fileList.length0 || _that.data.judgedetaillist[_k].fileListnull || _that.data.judgedetaillist[_k].fileListundefined){_that.data.judgedetaillist[_k].fileList[];}_that.data.judgedetaillist[_k].fileList.push({url:img.c_url});_that.setData({judgedetaillist:_that.data.judgedetaillist})}}})})}console.log(JSON.stringify(this.data.judgedetaillist));return false;}代码问题 
我这代码的设想是 遍历储存上传文件的 fileList数组-》wx.uploadFile上传到服务器-》返回服务器路径-》将返回的路径传送到 judgedetaillist.fileList中-》judgedetaillist传输到后台新增评论 这个代码执行下来会出现问题即在 wx.uploadFile后获取了对应的url存储到judgedetaillist中后 console.log(JSON.stringify(this.data.judgedetaillist)); 会出现 fileList:[] 但是 如果打印 console.log(this.data.judgedetaillist); 会出现 fileList: Array(1) 0: url: “/upload/judge/16654684.png” proto: Object length: 1 nv_length: (…) proto: Array(0) 在预设的对象中又能读取到数据此时再打印 console.log(this.data.judgedetaillist[0].fileList.length); 发现明明数组中有对象但是这个对象根本取不到并且连length都无法读取 
原因剖析 
由于wx.uploadFile默认是使用异步因此在不断的for循环中它返回的值并不是同步的导致多个同时执行此时数组使用的是地址引用并没有实际赋值成功赋值的数组已经被修改了因为原来的长度是0所以获取不到数组但又包含修改后的结果。 要解决这个bug就是让wx.uploadFile可以同步执行需要用到 1、new Promise 2、asyncawait 3、取消forEach forEach 中使用 async/await 时异步操作并不会等待前一个操作结束再执行下一个而是会同时执行多个异步操作 
解决方案非生产环境代码 
本来h5中的多图片上传是直接使用 async:false就可以但是在微信中这是无效的。所以代码写成这样 
解决方案一 
使用new Promise配合asyncawait进行多次循环 
//图片上传函数
Upload: function (uploadFile) {return new Promise((resolve, reject)  {wx.uploadFile({   //这里一定要用  wx.uploadFile 否则无法穿到后台filePath: uploadFile, //你要上传的路径name: file,   //你上传到后台的name值formData: {    // 如果你要验证你的token 可以用formData来给后台传值path: judge},url: 上传路径,success: (res)  {// 上传完成操作const data  JSON.parse(res.data)resolve({data: data})},fail: (err)  {//上传失败修改pedding为rejectwx.showToast({title: 网络出错,上传失败,icon: none,duration: 1000});reject(err)}});})},//接收返回的路径关键是async await 
async submit() {let tmparr  null;for (var k  0; k  this.data.judgedetaillist.length; k) {let _k  k;//图片上传for (let i  0; i  this.data.fileList[_k].length; i) {tmparr await this.Upload(this.data.fileList[_k][i].url);if(this.data.judgedetaillist[_k].fileListnull || this.data.judgedetaillist[_k].fileListundefined){this.data.judgedetaillist[_k].fileList[];}this.data.judgedetaillist[_k].fileList.push({ url: tmparr.data.c_url });this.setData({judgedetaillist: this.data.judgedetaillist})}}console.log(JSON.stringify(this.data.judgedetaillist));
}解决方案二 
利用Promise.all当所有的异步请求成功后才会执行将全部异步执行完后的数据一次性返回 调用测试 console.log(this.uploadImage(this.data.fileList[_k])) 返回结果 Promise {} proto: Promise [[PromiseState]]: “fulfilled” [[PromiseResult]]: Array(3) 0: “/upload/judge/1691391628202skmda.png” 1: “/upload/judge/1691391628219ttxps.png” 2: “/upload/judge/1691391628227yehwf.png” length: 3 nv_length: (…) proto: Array(0) 利用这个可以一次性获取全部的结果 
代码示例 
uploadImage: function(tempFilePaths){return new Promise((presolve,preject){if({}.toString.call(tempFilePaths)![object Array]){throw new TypeError(上传图片参数 tempFilePaths 类型错误!)}//路径数组为空时  不上传if(tempFilePaths.length0){presolve([])return}let uploads  []tempFilePaths.forEach((item,i){uploads[i]  new Promise ((resolve){console.log(item);wx.uploadFile({   //这里一定要用  wx.uploadFile 否则无法穿到后台filePath: item.url, //你要上传的路径name: file,   //你上传到后台的name值formData: {    // 如果你要验证你的token 可以用formData来给后台传值path: judge},url: 你的上传路径,success(res){console.log(res);resolve(JSON.parse(res.data).c_url)},fail(err){console.log(err)}})})})Promise.all(uploads).then(res{//图片上传完成presolve(res)}).catch(err{preject(err)wx.showToast({title:上传失败请重试,icon:none})})})},