Promise常使用的业务场景

278 阅读2分钟

前言

整理下业务中常用的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()