Promise 将异步变同步,解决uni.compressImage()多图压缩上传

前段时间在用uniapp做项目时,多个图片同时进行压缩上传时,uni.compressImage()这里是一个异步处理,还没等图片全部压缩完成,就已经开始后台上传文件操作了,但是uni.compressImage()这个方法本身没有异步转同步的属性,这时候就用Promise对象解决了异步转同步的问题。

   //图片上传
			let uploadImgLength = this.imgList.length;
			if (uploadImgLength > 0) {
				//压缩图片需要使用Promise异步转同步处理
				let promise = new Promise(function(resolve, reject) {
					_this.imgList.map((value, index) => {
						uni.compressImage({
							src: value.path,
							quality: 20,
							success: (res) => {
								_this.compressedImgList.push(res.tempFilePath);
								if (index == uploadImgLength - 1) {
									resolve(_this.compressedImgList);
								}
							},
							fail: (err) => {
								reject(err)
							}
						})
					})
				})
				promise.then(res => {
					console.log(res);
					let imgs = res.map((value, index) => { //picA picB picC 命名方式
						switch (index) {
							case 0:
								index = "A";
								break;
							case 1:
								index = "B";
								break;
							case 2:
								index = "C";
								break;
						}
						return {
							name: 'pic' + index,
							uri: value
						}
					})
					uni.request({
						url: _this.GLOBAL.serverSrc + 'tree/treeExist',
						method: 'POST',
						data: {
							stree_no: data.stree_no
						},
						success: res => {
							if (res.data == 0) {
								uni.showLoading({
									title: '苗木录入中'
								})
								uni.uploadFile({
									url: _this.GLOBAL.serverSrc + 'upload/uploadTreeImage?userid=' + this.userInfo.id + '&gardenId=' +
										data.garden_id,
									files: imgs,
									fileType: 'image',
									success: (res) => {
										console.log(res);
										let result = JSON.parse(res.data);
										if (result.result == 1) {
											data.picname = result.data;
											data.token = JSON.stringify(uni.getStorageSync('uerInfo'));
											//添加数据
											uni.request({
												url: this.GLOBAL.serverSrc + 'tree/addTree',
												method: 'POST',
												data: data,
												header: {
													"content-type": "application/x-www-form-urlencoded"
												},
												success: res => {
													if (res) {
														uni.hideLoading();
														uni.showToast({
															title: '录入成功',
															duration: 2000
														})
													}
												}
											});
										}
									}
								})
							} else {
								uni.showToast({
									title: '苗木编号已存在',
									icon: 'none',
									duration: 2000
								})
							}
						}
					})
				})

			}
   

在这个就明白了就很容易理解Promise 是怎么做的异步转同步,以上代码中可以看到resolve 和 reject 俩个参数
resolve()是将Promise的状态由未完成变为成功
reject()是将Promise的状态由未完成变为失败

我们只有将Promise 的状态置为成功,才会进行下一步动作

let promise = new Promise(function(resolve, reject) {
					_this.imgList.map((value, index) => {
						uni.compressImage({
							src: value.path,
							quality: 20,
							success: (res) => {
								_this.compressedImgList.push(res.tempFilePath);
								if (index == uploadImgLength - 1) {
									resolve(_this.compressedImgList);
								}
							},
							fail: (err) => {
								reject(err)
							}
						})
					})
				})

那么上面就是用一个if语句判断我什么时候才将Promise置为成功,并在resolve(_this.compressedImgList);专递下一步动作需要用到的变量,这个时候就可以用Promise.then()来接受变量并执行下一步操作

promise.then(res => {
					console.log(res);
}

这个时候console.log打印出来的res正是_this.compressedImgList传递的内容。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
如果你不想使用`uni.compressImage`方法来压缩图片,也可以使用其它的第三方库或者自己写代码来实现图片压缩。以下是一种通用的压缩图片的方法: ``` /** * 压缩图片 * @param {string} imgData 图片的Base64数据 * @param {number} maxWidth 图片最大宽度 * @param {number} maxHeight 图片最大高度 * @param {number} quality 压缩质量(0-1之间的小数) * @return {Promise} 压缩后的Base64数据 */ function compressImage(imgData, maxWidth, maxHeight, quality) { return new Promise(function(resolve, reject) { var img = new Image() img.src = imgData img.onload = function() { var canvas = document.createElement('canvas') var ctx = canvas.getContext('2d') var w = img.width var h = img.height var ratio = 1 if (w > maxWidth) { ratio = maxWidth / w } else if (h > maxHeight) { ratio = maxHeight / h } w *= ratio h *= ratio canvas.width = w canvas.height = h ctx.clearRect(0, 0, w, h) ctx.drawImage(img, 0, 0, w, h) var base64 = canvas.toDataURL('image/jpeg', quality) resolve(base64) } img.onerror = function() { reject(new Error('Failed to load image')) } }) } ``` 使用该方法压缩图片的步骤如下: 1. 将原始图片转换为Base64格式。 2. 调用`compressImage`方法进行压缩,并传入最大宽度、最大高度和压缩质量等参数。 3. 在返回的Promise对象的回调函数中获取压缩后的Base64数据。 以下是示例代码: ``` uni.chooseImage({ count: 1, success: function (res) { var tempFilePaths = res.tempFilePaths uni.getFileSystemManager().readFile({ filePath: tempFilePaths[0], encoding: 'base64', success: function (data) { compressImage(data.data, 800, 800, 0.8).then(function (base64) { console.log(base64) // 压缩后的图片Base64数据 }) } }) } }) ``` 在上面的示例中,首先使用`uni.chooseImage`方法选择一张图片,然后使用`uni.getFileSystemManager().readFile`方法将图片文件读取为Base64格式。接着调用`compressImage`方法进行压缩,并传入最大宽度800、最大高度800和压缩质量0.8等参数。最后在返回的Promise对象的回调函数中获取压缩后的Base64数据。 需要注意的是,压缩图片会消耗CPU和内存资源,因此需要根据实际情况进行调整压缩参数,以免影响应用性能。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值