使用Promise.all来并行调用多个异步函数;依次同步调用函数

场景: 在一个 vue页,有个form表单数据需要使用到三个后端接口返回的数据(常见的就是详情回显,需要下拉数据),要求拿到三个接口返回的数据后,再赋值给表单form。


总结:将方法从同步执行改为并行执行的过程

一、原始同步执行方式--依次执行--慢

在原始代码中,dictCode()virtualMachineDataList()serviceDataList()这三个方法调用后端数据被依次执行,即在一个方法的then中或await后调用下一个方法 。这种同步执行方式 可能导致性能问题,导致页面加载loading时间特别长 ,特别是在处理大量数据时,因为每个方法都需要等待上一个方法执行完成后才能开始执行

修改前代码:

c 复制代码
const dictCode = async(codeList) => {
  try {
    const data = await dictCodeList({ })
    return data
  } catch {
    return {}
  }
}

const virtualMachineDataList = async() => {
  try {
    const data = await virtualMachineApi({ virtualMachineName: null })
    return data
  } catch {
    return {}
  }
}
const serviceDataList = async() => {
  try {
    const data = await serviceApi({ serviceName: null })
    return data
  } catch {
    return {}
  }
}

const generateLayout = async(mode, activeNode, option) => {

  // 为了确保拿到三个接口数据 而依次执行(类似then嵌套)---导致lodaing加载过长
  const dictValueList = await dictCode(codeList) || []
  const hostList = await virtualMachineDataList() || []
  const serviceList = await serviceDataList() || []

 // 使用dictValueList、hostList、serviceList数据
 // 此时再使用dictValueList.map  hostList.map   serviceList.map  
 // 给form赋值 return form

}

二、 解决方案:修改为并行执行

原三个方法不变动,我们只需将这三个方法放在了Promise.all中进行并行执行。这样可以确保这三个方法同时开始执行,而不需要等待上一个方法的执行结果。这样做可以显著提高性能,尤其是在处理大量数据或网络请求时。

Promise.all()提供了并行执行异步操作的能力。并且在所有异步操作执行完成以后,才执行回调。
Promise.all()详细使用方法参考此篇
修改后:通过network可以发现三个接口是同时调用的

c 复制代码
const dictCode = async(codeList) => {
  try {
    const data = await dictCodeList({ })
    return data
  } catch {
    return {}
  }
}

const virtualMachineDataList = async() => {
  try {
    const data = await virtualMachineApi({ virtualMachineName: null })
    return data
  } catch {
    return {}
  }
}
// 可以给第二个方法设置延时触发 更明显看到三个方法是并行执行效果
// const virtualMachineDataList = async() => {
//   return new Promise((resolve, reject) => {
//     setTimeout(async() => {
//       try {
//         const data = await virtualMachineApi({ virtualMachineName: null })
//         resolve(data)
//       } catch (error) {
//         reject(error)
//       }
//     }, 5000)
//   })
// } 

const serviceDataList = async() => {
  try {
    const data = await serviceApi({ serviceName: null })
    return data
  } catch {
    return {}
  }
}

const generateLayout = async(mode, activeNode, option) => {

  // 并行调用三个异步函数--分别获取到三个接口返回的数据 参数数据和[]数组里调用方法返回的对应
  const [dictValueList, hostList, serviceList] = await Promise.all([
    dictCode(codeList),
    virtualMachineDataList(),
    serviceDataList()
  ])

 // 使用dictValueList、hostList、serviceList数据
 // 此时再使用dictValueList.map  hostList.map   serviceList.map  
 // 给form赋值 return form

}

问题解决

通过将方法改为并行执行,我们解决了以下问题:

  1. 性能瓶颈:原来的同步执行方式可能导致性能瓶颈,特别是在处理大量数据或网络请求时。并行执行可以提高性能,减少整体执行时间。
  2. 并行性:通过并行执行,我们确保了这三个方法可以同时开始执行,而不需要等待上一个方法的执行结果。这提高了并行性,有助于提高系统的吞吐量和响应速度。

结论

通过将方法从同步执行改为并行执行,我们解决了性能瓶颈和并行性的问题,提高了系统的性能和响应速度。这种修改对于处理大量数据或网络请求的场景特别有帮助。


相关推荐
清灵xmf8 天前
JavaScript 中如何识别异步函数?
开发语言·javascript·async·异步函数
Trouvaille ~2 个月前
【Python篇】Python 函数综合指南——从基础到高阶
开发语言·python·生成器·异步函数·高阶函数·匿名函数·闭包
可达鸭头上站青蛙10 个月前
循环异步调取接口使用数组promiseList保存,Promise.all(promiseList)获取不到数组内容,then()返回空数组
javascript·promise·promise.all·图片文件上传
仙魁XAN1 年前
Unity C# 之 Task、async和 await 结合使用的一些情况处理
unity·c#·async/await·task·异步函数