uniapp 等图片文件全部上传成功后,再继续执行js代码
起因
- 前几天在写一个简单表单提交的时候,遇到了一个文件上传的问题。这个表单,需要上传三类图片,而且每一类都是可以多张上传的。
- 使用文件上传的组件,一般都是选择图片后,他就会自动进行服务器的上传,但是我很难去判断要上传的图片,是不是已经全部上传成功了(后端同学不给写批量上传,又是一个我下决定学学后端的原因)。
- 我使用了一个定时器,去循环判断是不是图片全部上传成功了(这方法太傻了,而且极易出问题)。结果,在测试的时候,发现,很多手机 上传了图片提示没上传,或者是上传后就卡住了,再或者无法提交表单。
- 在本地测试的是没问题的,但是在真机上处理不少问题。
分析排查问题 - 后来发现,是因为用户图片文件过大,上传速度较慢,导致的。还没等图片上传成功,就开始继续执行下面的js代码。
- 两个问题
- 上传图片过大 => 需要对图片进行压缩,但是不能过度压缩,因为这图片是用户上传的资料,需要查看的
- js 代码执行的一个同异步 问题
解决方案 - 图片压缩 使用 uniapp 插件库中的
- 处理图片上传的同步异步问题 使用 Promise 加 async await
代码
<!-- 其他表单内容 -->
<!--上传组件-->
<uni-file-picker ref="upload" v-model="upLoad.hkbimages" @select="uploadHkbimages"
@delete="remove"></uni-file-picker>
<u-button :ripple="true" hover-class="none" shape="circle" :hair-line="false"
type="default" @click="submitMsg">提交信息</u-button>
<!-- 图片压缩组件 -->
<x-compress ref="xCompress" />
// 引入 uniapp 上传组件
import uniFilePicker from "components/uni-file-picker/uni-file-picker.vue"
// 引入下载后的 图片压缩组件
import xCompress from 'components/x-compress/x-compress.vue';
export default {
components: {
datetimePicker,
xCompress
},
data(){
return{
upLoad:{
hkbimages:[],
},
info:{
hkbimages:[]
},
child:{
hkbimages:[]
}
}
},
methods:{
uploadHkbimages(imgList){
// 此处是 在用户移出图片再添加 保证 图片列表内容正确
this.info.hkbimages = this.info.hkbimages.slice(0, this.$refs.upload.files.length - 1);
// 进行图片压缩
let result = await this.$refs.xCompress.compress(imgList, {
base64: true,
maxW: 1024,
maxH: 1024,
quality: 0.6,
showLoading: true,
mask: true,
})
// 将压缩后的图片格式进行处理
this.info.hkbimages = this.info.hkbimages.concat(result.map(v => v.base64));
},
remove(){
this.info.hkbimages = this.info.hkbimages.slice(0, this.$refs.upload1.files.length - 1);
},
async submitMsg(){
/* 表单其他项验证。
*/
if(!this.info.hkbimages.length)
{
uni.showToast{
icon:"none",
title:"请先上传XXX图片"
}
return;
}
// 同步处理 图片上传
let imgs = await this.uploadFile(this.info.hkbimages);
imgs.forEach(v => {
let url = JSON.parse(v[1].data).data.url;
this.child.hkbimages.push(url);
})
/* 上传返回的图片地址 和其他表单内容进行提交..
*/
},
uploadFile(imgs) {
try {
let tasks = [];
let imgArr = [];
imgs.forEach(url => {
tasks.push(uni.uploadFile({
url: Config.httpUrl + '/api/common/upload',
name: 'file',
filePath: url,
}));
})
return Promise.all(tasks);
} catch (err) {
console.log(err);
throw new Error(err);
}
},
}
}