之前写过一篇ES6异步处理方式: Promise / async await,对Promise和async await 有了简单的理解,但后来才发现我的理解太浅了,只是记录了基本知识而已。
在上家公司,遇到过需要发送多个总数不定的ajax的需求,当时的解决方式是使用递归,一个请求结束之后再发另一个,当时还以为自己很机智,写了这篇博客:javascript递归的实际应用场景。
所以当前两周,我遇到小程序的图片上传的问题(小程序的图片上传使用wx.uploadFile
接口,但该接口不支持批量上传图片,上传n张图片就需要发送n个请求)时,就顺势想到了递归。但当我完成之后,却被同事点化了, 告诉我可以用Promise.all
来很轻松的解决这个问题。
参考资料:
因为这件事情,得到了一个重要的教训:了解新知识,一开始理解比较浅没关系,但一定要全面,带着思考去看,搞清楚它能解决什么问题。达到在工作中遇到了相应的场景,才能想到他。
我当时就是因为不够全面,以至于忘记了还有Promise.all的存在,才很笨的绕了远路。
小程序图片上传
小程序上传图片的思路是先用wx.chooseImage
选取图片,然后在成功回调中上传,选取的代码如下:
wx.chooseImage({
count: this.maxImgCount, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: res => {
// 最多n张图片,多选了取前n个
this.localImgPaths = [...res.tempFilePaths, ...this.localImgPaths].splice(0, this.maxImgCount);
this.show = true;
this.textareaFocus = true;
}
});
然后在需要时将选中的图片进行上传:
async uploadImg() {
uploadedImgs = await localImgs2webImgs(this.localImgPaths);
// 使用上传成功之后的在线图片
console.log(uploadedImgs);
}
重点就在我们的localImgs2webImgs
:
/**
* 将本地图片文件地址数组变为上传后的在线图片url数组
* @param array filePaths
*/
export const localImgs2webImgs = (localImgs = []) => {
// 上传的后端url
const url = 'https://xxxxxxxxxxxx/upload';
// 因为多张图片且数量不定,这里遍历生成一个promiseList
let promiseList = localImgs.map((item) => {
return new Promise(resolve => {
wx.uploadFile({
url,
filePath: item,
name: 'images[]',
success: (res) => {
const data = JSON.parse(res.data).responseData.imageUrls[0];
resolve(data);
}
});
});
});
// 使用Primise.all来执行promiseList
const result = Promise.all(promiseList).then((res) => {
// 返回的res是个数据,对应promiseList中请求的结果,顺序与promiseList相同
// 在这里也就是在线图片的url数组了
return res;
}).catch((error) => {
console.log(error);
});
return result;
};
Promise
Promise.all()
Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。并且,Promise.all返回的结果数组和他接收到的数组的顺序是一致的,
Promise.race()
顾名思义,Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
Promise.all()
和Promise.race()
都输入多个请求,区别在于:Promise.all()
输出多个请求结果,并且顺序跟输入相同;而Promise.race()
只输出第一个返回的结果。