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

如何改造JS限流函数,通过Promise获取被延迟执行函数的返回值

问题原因

你之前实现的Promise版本仅第一次返回Promise的核心原因是:当任务正在执行(isCalled=true)时,schedule函数不会进入if (canSchedule)分支,没有返回值,后续调用拿到的就是undefined,自然无法链式调用then获取结果。

改造后的实现

function rateLimter(fn, wait) {
  const queue = []
  let isCalled = false

  const schedule = async function () {
    const canSchedule = queue.length && !isCalled
    if (canSchedule) {
      isCalled = true
      // 取出队列里存的任务信息:绑定好的原函数、resolve、reject
      const { task, resolve, reject } = queue.shift()
      try {
        // 等待原函数执行完成,支持异步函数
        const result = await task()
        resolve(result)
      } catch (err) {
        // 异常处理
        reject(err)
      } finally {
        setTimeout(() => {
          isCalled = false
          schedule()
        }, wait)
      }
    }
  }

  return function (...args) {
    // 每次调用直接返回Promise,保证调用方一定能拿到Promise实例
    return new Promise((resolve, reject) => {
      // 把任务和对应的resolve/reject一起存入队列
      queue.push({
        task: fn.bind(this, ...args),
        resolve,
        reject
      })
      schedule()
    })
  }
}

核心改造点

  • 每次调用限流包装后的函数时,直接创建Promise实例返回,不管当前是否有正在执行的任务,都能保证调用方拿到Promise对象可以链式调用then/catch
  • 队列中存储的不再是单独的绑定后函数,而是同时携带对应Promise的resolve和reject方法,任务执行完成后直接调用对应方法传递结果
  • 新增异常处理逻辑,原函数执行抛出的错误可以通过catch捕获
  • 支持异步原函数,会等待原函数执行完成后再传递返回值

使用你提供的测试用例运行时,会按照1秒间隔依次输出10、11、12,符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 10:12:01