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

编写通用封装函数限制Promise.allSettled()调用频率的问题

解决AWS SDK v3批量执行命令的TypeScript类型错误

问题背景

使用AWS JavaScript SDK v3时,批量并行提交API命令(超过10个)会失败,需要编写通用分批执行函数,但调用client.send()时出现TypeScript错误:

This expression is not callable. Each member of the union type '{ <InputType extends ServiceInputTypes, OutputType extends ServiceOutputTypes>(command: Command<...>): Promise<...>; ... }' has signatures, but none of those signatures are compatible with each other.ts(2349)

错误根源

当客户端是多个AWS服务客户端的联合类型,或者命令数组包含不同服务的命令时,TypeScript无法推断出send方法的兼容签名——不同服务客户端的send方法泛型约束(如各自的ServiceInputTypes/ServiceOutputTypes)存在差异,导致联合后的方法签名无法统一匹配。

解决方案

方案1:限定单一客户端与匹配命令(推荐)

针对同一服务的批量命令,通过泛型约束明确客户端与命令的类型匹配,避免联合类型冲突:

import { Command, SmithyResolvedConfiguration } from "@aws-sdk/smithy-client";

/**
 * 分批执行同一客户端的API命令
 * @param client AWS服务客户端实例
 * @param commands 与客户端匹配的命令数组
 * @param batchSize 每批并行执行的命令数量,默认10
 * @returns 所有命令的执行结果(已settled)
 */
async function batchExecute<
  Client extends {
    send: <InputType, OutputType>(
      command: Command<any, InputType, any, OutputType, SmithyResolvedConfiguration<any>>
    ) => Promise<OutputType>;
  },
  Cmd extends Command<any, any, any, any, SmithyResolvedConfiguration<any>>
>(
  client: Client,
  commands: Cmd[],
  batchSize: number = 10
): Promise<PromiseSettledResult<Awaited<ReturnType<Client['send']>>>[] {
  const results: PromiseSettledResult<any>[] = [];

  for (let i = 0; i < commands.length; i += batchSize) {
    const batch = commands.slice(i, i + batchSize);
    const batchResults = await Promise.allSettled(
      batch.map(command => client.send(command))
    );
    results.push(...batchResults);
  }

  return results;
}

// 使用示例(S3客户端)
import { S3Client, ListObjectsV2Command, PutObjectCommand } from "@aws-sdk/client-s3";

const s3Client = new S3Client({ region: 'us-east-1' });
const s3Commands = [
  new ListObjectsV2Command({ Bucket: 'my-bucket' }),
  new PutObjectCommand({ Bucket: 'my-bucket', Key: 'test.txt', Body: 'hello world' }),
  // 更多S3命令...
];

const allS3Results = await batchExecute(s3Client, s3Commands);

方案2:支持多客户端混合命令(牺牲部分类型安全)

如果需要跨服务批量执行命令,可通过类型断言绕过TypeScript的严格检查:

import { Command } from "@aws-sdk/smithy-client";

/**
 * 分批执行多客户端混合API命令
 * @param tasks 包含客户端与对应命令的任务数组
 * @param batchSize 每批并行执行的任务数量,默认10
 * @returns 所有任务的执行结果(已settled)
 */
async function batchExecuteMixed(
  tasks: Array<{ client: any; command: Command<any, any, any, any, any> }>,
  batchSize: number = 10
): Promise<PromiseSettledResult<any>[]> {
  const results: PromiseSettledResult<any>[] = [];

  for (let i = 0; i < tasks.length; i += batchSize) {
    const batch = tasks.slice(i, i + batchSize);
    const batchResults = await Promise.allSettled(
      batch.map(({ client, command }) => client.send(command as any))
    );
    results.push(...batchResults);
  }

  return results;
}

// 使用示例(混合S3与DynamoDB命令)
import { DynamoDBClient, ScanCommand } from "@aws-sdk/client-dynamodb";

const mixedTasks = [
  { client: s3Client, command: new ListObjectsV2Command({ Bucket: 'my-bucket' }) },
  { client: new DynamoDBClient({ region: 'us-east-1' }), command: new ScanCommand({ TableName: 'my-table' }) },
];

const mixedResults = await batchExecuteMixed(mixedTasks);

关键说明

  • 方案1通过泛型约束保证了类型安全性,是批量处理同一服务命令的最优选择;
  • 方案2适合跨服务批量操作场景,但会丢失部分类型检查能力,需自行确保客户端与命令的匹配性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 15:10:16