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

不使用async/await如何实现仅用局部变量存结果的Promise串行调用times函数

实现方案

你需要的仅使用函数局部变量存储结果、不破坏原有函数签名、不依赖async/await的实现如下:

const times = (fn: (...args: any) => Promise<any>, n: number = 1) => {
  // 仅当前times调用生效的局部结果数组,多次调用times互不干扰
  const results: any[] = []
  // 内部递归辅助函数处理串行调用逻辑
  const step = (remaining: number): Promise<any[]> => {
    if (remaining === 0) return Promise.resolve(results)
    return fn().then(res => {
      results.push(res)
      return step(remaining - 1)
    })
  }
  return step(n)
}

方案说明

  • 完全满足所有约束:没有使用模块级全局变量、没有修改原函数签名、没有使用async/await语法、没有在函数对象上挂载额外属性
  • 解决了原实现的隐藏问题:原实现挂载在函数上的results是共享属性,多次调用times会出现结果互相污染的情况,本实现的results是每次调用times的局部变量,不同调用完全隔离
  • 串行逻辑保持不变:必须等前一次fn返回的Promise状态变为fulfilled后,才会触发下一次fn调用,执行顺序完全符合要求

测试验证

你原来的使用示例无需修改即可直接运行:

const createPromise = (args: any) =>
  new Promise((resolve) => {
    setTimeout(() => {
      console.log(`[${new Date().toISOString()}]args: `, args);
      resolve(args);
    }, 1000);
  });

async function test() {
  const actual = await times(() => createPromise('data'), 3);
  console.log(actual);  // 输出: [ 'data', 'data', 'data' ]
}
test()

如果要避免测试代码使用async/await,也可以写成Promise链式调用的形式:

times(() => createPromise('data'), 3).then(actual => {
  console.log(actual); // 输出: [ 'data', 'data', 'data' ]
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 13:57:03