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);
				}
			},
			
		}
	}
  • 多个上传控件也是一样操作