【问题标题】:How can i wait for multiple async calls?我如何等待多个异步调用?
【发布时间】:2021-07-01 12:39:39
【问题描述】:

我有多个异步调用。比如四个

this.lazyLoadData();
this.lazyLoadData();
this.lazyLoadData();
this.lazyLoadData();

问题是每个 http 请求可能需要不同的时间。 在每个请求中,我都会发送不同的查询参数以在后端获取分页数据。

所以在这种情况下,第一个 this.lazyLoadData 有时可能会晚于第二个 - 取决于后端的分页结果。

为了防止这种行为,我尝试使用async and await

await this.lazyLoadData();
await this.lazyLoadData();
await this.lazyLoadData();
await this.lazyLoadData();

async lazyLoadData(cb?) {
  const filtersParam: any = {
        page: this.filterService.dashboardPage,
        size: 25,
      }

      let response = await this.processMonitorService.monitoring(filtersParam);
      response.then(data => {
         console.log('maked http call');
      });
      ...
}

但问题是,即使我使用 async 和 await - 这四个 http 调用并没有按顺序发生。

所以在一秒钟的时间内我调用了四次lazyLoadData,我在那里等待每个结果 但响应不按顺序排列。所以有时第三个会在第二个之前执行,等等......

我该如何解决这个问题?

【问题讨论】:

  • console.log('maked http call'); 到底发生了什么?如果你在那里有另一个承诺,那么你应该返回它。无论如何,你应该await 打一个then 电话。
  • this.processMonitorService.monitoring 是做什么的?你确定它返回一个承诺,如果是,它会在 HTTP 调用收到响应时解决吗?
  • 它返回 Observable,我需要转换它 - this.processMonitorService.monitoring.toPromise() 所以 await 可以工作

标签: javascript asynchronous async-await


【解决方案1】:

为什么你需要它们井井有条?难道你不能提前有所需的参数,然后按顺序使用结果。

当然,你可以让他们等待,但这会损害整体性能:

this.lazyLoadData().then(() => this.lazyLoadData())

等等

但是,如果您不依赖状态,而是让参数来自外部,那会​​更好。例如:

await this.lazyLoadData(1);
await this.lazyLoadData(2);
await this.lazyLoadData(3);
await this.lazyLoadData(4);

其中参数是页码。

顺便问一下,发出 4 个请求的一般用例是什么?如果您同时需要所有 4 个页面,您不能只请求 100 的页面大小吗?

【讨论】:

  • 不,有复杂的逻辑,它们在 java 脚本滚动事件中完成,但无论如何我有时需要连续执行四个
【解决方案2】:

我认为最好的方法是使用Promise.all()

您的代码将如下所示:

    const arrayOfPromises = [
        this.lazyLoadData(1),
        this.lazyLoadData(2),
        this.lazyLoadData(3),
        this.lazyLoadData(4),
    ]

    Promise.all(arrayOfPromises).then((result) => {
        console.log(result) // this will contain the result of the 4 requests in order
    })

此外,您需要在代码中进行一些重构。

你的lazyLoadData函数变成如下

    async lazyLoadData(cb ? ) {
        const filtersParam: any = {
            page: this.filterService.dashboardPage,
            size: 25,
        }

        return this.processMonitorService.monitoring(filtersParam);
    }

【讨论】:

  • 但是使用 Promise.all 如果一个 http 请求失败,它们都不会被执行——我不需要那个 Heni
【解决方案3】:

你必须把你的代码放在一个异步函数中:

(async()=>{
  await this.lazyLoadData();
  await this.lazyLoadData();
  await this.lazyLoadData();
  await this.lazyLoadData();
}());

【讨论】:

  • 为什么要使用立即调用的函数?这实际上与 OP 的原始代码相同,不是吗?
猜你喜欢
  • 2013-08-03
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-15
相关资源
最近更新 更多