You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React Hook中聚合多个Promise的返回结果?

问题解决方法

问题根源

你当前代码的核心问题是异步操作未等待完成就同步返回结果:api.get返回的是Promise实例,then回调属于异步微任务,会在当前同步代码执行完毕后才触发。你在循环结束后直接返回results数组时,所有接口请求都还没有返回响应,因此数组永远是空值。

如果你之前尝试async/await写法未生效,通常是仅修改了getAll内部逻辑,没有在调用getAll的位置添加await,且调用getAll的外层函数没有添加async标识导致的。

修正后的自定义Hook代码

function useMyHook() {
  const api = useApiService();

  return {
    getAll,
  };

  // 修改返回类型为Promise<MyType[]>,添加async标识
  async function getAll(arr: number[]): Promise<MyType[]> {
    // 生成所有请求的Promise数组
    const requestPromises = arr.map(u => api.get(u));
    // 等待所有请求完成,拿到所有返回结果
    const allResults = await Promise.all(requestPromises);
    // 合并数组并去重后返回
    return [...new Set(allResults.flat())];
  }
}

组件内调用方式

function MyComponent() {
  // ...
  const myHook = useMyHook();
 
  // 调用函数添加async标识
  const handleUse = async () => {
    // ...
    const numbers = [1, 2, 3];
    // 等待异步方法返回结果
    const myTypes = await myHook.getAll(numbers);
    const count = myTypes.length; // 此时可拿到正确的结果长度
    // ...
  };
}

可选优化点

  • 如果需要容忍部分请求失败,不影响其他正常返回的结果,可以把Promise.all替换为Promise.allSettled,再过滤出成功的请求结果:
async function getAll(arr: number[]): Promise<MyType[]> {
  const requestPromises = arr.map(u => api.get(u));
  const allResults = await Promise.allSettled(requestPromises);
  const validResults = allResults
    .filter((item): item is PromiseFulfilledResult<MyType[]> => item.status === 'fulfilled')
    .map(item => item.value);
  return [...new Set(validResults.flat())];
}
  • 如果需要在组件卸载时中断未完成的请求,可以结合AbortController实现请求取消,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Heldenkrieger01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 07:06:04