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

如何在不修改主代码时合并TypeScript Promise实现单次API请求?

问题描述

现有如下TypeScript代码:

async function my_function(arg: string): Promise<string> 
{  
    fetch("http://localhost:8000/api.php?args=" + arg);
    ...
}

const items = ["100","98","35","400"];
let result = await Promise.all(items.map(my_function)); 

我的API支持多参数请求:

http://localhost:8000/api.php?args=100,98,35,400

注意我只能修改my_function的函数体代码,不能更改该函数签名。请问能不能在my_function内部把其他Promise合并,实现只发起一次fetch请求且不修改主代码的目标?

解决方案

完全可以实现,核心思路就是用函数静态变量或闭包来收集同一批次调用的参数,延迟发起请求,等所有参数收集完毕后只发一次请求,再把结果分发给各个调用对应的Promise。

具体实现代码如下:

async function my_function(arg: string): Promise<string> {
  // 用static变量跟踪当前批次的请求状态,同批次所有调用共享这些变量
  static batch: {
    args: string[],
    resolver: (results: string[]) => void
  } | null = null;
  static batchPromise: Promise<string[]> | null = null;

  return new Promise((resolve) => {
    // 如果当前没有正在处理的批次,初始化新批次
    if (!batch) {
      batch = { args: [], resolver: null! };
      // 创建一个Promise,等待参数收集完再发起请求
      batchPromise = new Promise<string[]>((res) => {
        batch!.resolver = res;
        // 用setTimeout延迟执行,确保Promise.all里的所有my_function调用都能把参数加进来
        setTimeout(async () => {
          try {
            // 发起批量请求
            const response = await fetch(`http://localhost:8000/api.php?args=${batch!.args.join(',')}`);
            // 假设API返回的结果数组顺序和参数顺序一致,根据实际情况调整解析逻辑
            const results = await response.json();
            batch!.resolver(results);
          } catch (err) {
            // 错误处理:给所有Promise返回默认值,或者抛出错误,按需调整
            batch!.resolver(batch!.args.map(() => ''));
          } finally {
            // 重置批次状态,准备处理下一批请求
            batch = null;
            batchPromise = null;
          }
        }, 0);
      });
    }

    // 把当前参数加入批次
    batch.args.push(arg);
    // 等待批量请求完成,根据参数索引返回对应结果
    batchPromise.then((results) => {
      const index = batch!.args.indexOf(arg);
      resolve(results[index]);
    });
  });
}

要点说明

  • 这里用了TypeScript函数的static属性来存储批次状态,也可以用模块级的变量替代,效果一样。
  • setTimeout的作用是给Promise.all中的所有my_function调用留足时间收集参数,确保不会提前发起请求。
  • 假设API返回的结果数组顺序和传入的参数顺序完全匹配,如果API返回的是键值对(比如{ "100": "结果1", "98": "结果2" }),需要把结果匹配逻辑改成resolve(results[arg])即可。
  • 错误处理部分可以根据业务需求调整,比如统一抛出错误,或者给每个调用返回特定的错误值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 19:22:49