前言
整理下业务中常用的Promise使用场景,后面还会陆续补充新的。
Promise.then()
场景:处理异步请求嵌套,下个请求依赖与上个请求的结果
const getExDetail = () => {
querySwitch(params).then((res) => {
return queryDetail({id: res.id})
}).then((result) => {
console.log(result)
}).catch(({error}) => {
message.error(error)
});
};
Promise.all()
数组成员中所有的promise实例状态都变为fulfilled,all()状态变为fulfilled。或则有一个变为rejected,all()状态变为rejected。
场景:处理一组promise异步请求
通过一组图片的每个前缀url,依次异步请求获取图片自己的base64码然后渲染图片
//index.vue
//template
<li class="policy-img" v-for="(it,index) in imageInfos">
<img :src="it.imgUrl" alt/>
<i @click="imageInfos.splice(index,1)">×</i>
</li>
//js methods
const getAllImgB64Str = (imageInfos) => {
let promiseArr = [];
imageInfos.forEach(it => {
let _param = {imgUrl: it.imgUrl, imgId: it.imgId}
promiseArr.push(getImgB64StrApi(baseUrl, _param));
});
Promise.all(promiseArr).then(res => {
this.imageInfos = res.map(result => {
let temObj = {};
if (result.code === "0200") {
temObj.imgUrl = `data:image/png;base64,${result.data.data.imgBase64String}`;
} else {
this.showPosition("middle", result.data.message);
}
return temObj;
});
}).catch(err=>{
console.log(err)
});
}
//调用方法
getAllImgB64Str(this.imageInfos);
Promise.race()
数组成员中有一个promise实例状态发生变化,不管是fulfilled还是rejected,Promise.race()会跟随第一个状态而变化。
场景:可以处理超时请求
//延时处理
const reqTimeOut = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject('请求超时,请刷新页面')
}, 5000)
})
}
const reqTimeOutHandle = (promiseArr)=>{
Promise.race(promiseArr)
.then((result) => {
console.log(result)
}).catch(err => console.log(err))
}
//某个API请求
const requestApi = () => {
return post('request.api', params)
}
reqTimeOutHandle([requestApi(), reqTimeOut()])
//异步加载图片
function loadImageAsync(url){
return new Promise(function(reslove,reject){
const image = new Image();
image.onload = function (){
reslove(image)
};
image.onerror = function (){
reject(new Error('could not load image at'+url))
};
image.src = url
})
}
reqTimeOutHandle([loadImageAsync(), reqTimeOut()])
Promise.allSettled()
等待参数数组所有的promise实例成员状态发生了变化,不管是fulfilled或者rejected,Promise.allSettled()的状态才会变化并且使用then()回调处理结果
场景1:页面多个并发清楚集中处理数据
比如一个电商列表页面并发执行多少个请求,比如banner列表数据,商品列表数据,分类信息数据
如果前面请求失败了也不能中断后续的请求,可以使用一个loading效果,等待所有接口都返回后再结束loading
然后再集中处理 成功的数据和失败的信息。
let initDatas = {
bannerList: [],
goodsList: [],
typeList: [],
}
let dataKeys = ['bannerList', 'goodsList', 'typeList']
const getBannerList = () => {
return post('getBannerList.api', {token})
}
const getGoodsList = () => {
return post('getGoodsList.api', {token})
}
const getTypeList = () => {
return post('getTypeList.api', {token})
}
const initDatasHandle = () => {
loading(true)
Promise.allSettled([getBannerList(),getGoodsList(),getTypeList()]).then((results) => {
results.forEach((item, index) => {
if (item.status === 'fulfilled') {
// 异步操作成功时返回
// {status: 'fulfilled', value: value}
initDatas[dataKeys[index]] = item.value
} else {
// 异步操作失败时返回
// {status: 'rejected', reason: reason}
console.log(item.reason)
}
})
loading(false)
})
}
initDatasHandle()