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

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


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

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

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

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可以发现三个接口是同时调用的

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. 并行性:通过并行执行,我们确保了这三个方法可以同时开始执行,而不需要等待上一个方法的执行结果。这提高了并行性,有助于提高系统的吞吐量和响应速度。

三、异步改成同步(补充)

情景:在methods的某个方法内,想要在获取到接口数据后,在进行大量的逻辑书写(或者再调用下一个接口方法),原始方案就需要写成嵌套关系,形成回调地狱难以阅读。

修改前:执行顺序是2-4-3,逻辑赋值只能在3的位置书写,

    // 获取申请人信息
    getApplyUserList() {
      console.log(2)
      applyUserApi({}).then(res => {
        this.divisionList = res || []
        this.getPageList() // 嵌套调用获取页面数据接口
        console.log(3)
      }).finally(() => {
      })
      console.log(4)
    },

修改后:执行顺序是 1-2-3-4-5,可以在4的位置书写大量逻辑赋值等操作

  async created() {
    console.log(1)
    await this.getApplyUserList() // 可以 let data = await this.getApplyUserList()方法内的return数据
    console.log(5)
  },
   
	 // 获取申请人信息
    async getApplyUserList() {
      console.log(2)
      try {
        this.divisionList = await applyUserApi({})
        // return 可以return出await接口数据
        console.log(3)
      } catch (error) {
        console.log(error)
      }
      this.getPageList() // 依次执行的更清晰
      console.log(4)
    },

总结:可以理解为,设置async 和 await 后, 该方法{}内是同步逻辑

结论

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


  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Promise.all 是 JavaScript 中的一个方法,用于将多个 Promise 实例包装成一个新的 Promise 实例。这些原始的 Promise 实例在全部都变为 fulfilled 状态(成功状态)后,新的 Promise 实例才会变为 fulfilled 状态。如果有任意一个原始的 Promise 实例变为 rejected 状态(失败状态),那么新的 Promise 实例就会立刻变为 rejected 状态。 下面是一个使用 Promise.all 的示例: ``` const promise1 = Promise.resolve(3); const promise2 = 42; const promise3 = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'foo'); }); Promise.all([promise1, promise2, promise3]).then((values) => { console.log(values); }); // expected output: Array [3, 42, "foo"] ``` 在这个例子中,Promise.all 方法接受一个数组作为参数,这个数组包含三个 Promise 实例,并返回一个新的 Promise 实例。当所有的三个原始的 Promise 实例都变为 fulfilled 状态后,新的 Promise 实例才会变为 fulfilled 状态,并且传递给 then 方法的回调函数会被调用。 ### 回答2: Promise.all是一个方法,它接收一个Promise对象数组作为参数,并返回一个新的Promise对象。这个新的Promise对象会在所有的Promise对象都成功执行后被resolve,或者其中一个Promise对象出现错误后被reject。 使用Promise.all的好处是可以并行执行多个异步操作,并且在所有异步操作都完成后再进行下一步处理。例如,假设有三个异步操作a、b和c,我们希望在它们都完成后才执行下一步操作。我们可以将这三个异步操作封装为Promise对象,然后使用Promise.all来处理它们。 具体步骤如下: 1. 创建需要执行异步操作a、b和c的Promise对象。 2. 将这三个Promise对象放入一个数组中。 3. 调用Promise.all方法,将上一步中的数组作为参数传入。 4. 使用then方法来处理Promise.all返回的新Promise对象。在then方法中,我们可以获取到a、b和c异步操作的结果。 使用Promise.all的一个典型应用场景是同时请求多个接口并获取结果。当我们需要从多个接口获取数据时,可以使用Promise.all来并行请求,提高请求效率。 需要注意的是,如果Promise.all中的某个Promise对象出现错误,整个Promise.all的返回结果将会被reject。因此,我们需要在then方法中使用catch来处理异常情况。另外,如果Promise对象数组中有一个不是Promise对象,Promise.all将会报错。 总结来说,Promise.all提供了一种并行执行多个异步操作的方法,可以方便地处理多个异步任务的结果。它的使用可以简化异步编程,并提供更好的性能和可读性。 ### 回答3: Promise.all 是一个 Promise 静态方法,接收一个由 Promise 对象组成的数组作为参数,并返回一个新 Promise 对象。 当传入的数组中所有的 Promise 对象都变为 fulfilled 状态时,返回的 Promise 对象的状态才会变为 fulfilled,且返回值是一个数组,其中包含了所有 Promise 对象的返回值。 当传入的数组中任意一个 Promise 对象变为 rejected 状态时,返回的 Promise 对象的状态会变为 rejected,并返回第一个被 reject 的 Promise 对象的错误信息。 使用 Promise.all 的好处是可以同时处理多个异步操作,等到所有异步操作都完成后再做统一的处理。这样可以提高效率,减少代码的复杂度。 使用 Promise.all 的步骤如下: 1. 创建一个 Promise 对象数组,数组中的每个 Promise 对象代表一个异步操作。 2. 使用 Promise.all 方法,并将上一步创建的 Promise 对象数组作为参数传入。 3. 使用 then 方法来处理 Promise 对象,在回调函数中可以获取到所有异步操作返回的结果。 4. 使用 catch 方法来捕获异常并处理错误情况。 例如,下面的示例代码演示了使用 Promise.all 来同时请求多个接口的例子: ```javascript const promise1 = fetch('http://api1.example.com/data'); const promise2 = fetch('http://api2.example.com/data'); const promise3 = fetch('http://api3.example.com/data'); Promise.all([promise1, promise2, promise3]) .then(response => { // 处理返回的结果 console.log(response); }) .catch(error => { // 处理异常情况 console.error(error); }); ``` 上面的示例中,我们创建了三个 Promise 对象来请求三个不同的接口,然后使用 Promise.all 方法来同时处理这三个异步操作。当所有接口的请求都成功完成时,then 方法会返回一个包含了所有请求结果的数组,我们可以在回调函数中进行后续的操作。如果其中任意一个接口请求失败了,就会执行 catch 方法中的回调函数,来处理错误情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值