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

实现带返回最后计算结果的underscore _.throttle函数遇阻求助

问题分析与修复方案

你的核心问题在于混淆了节流和记忆化的逻辑,同时第一个版本完全失去了节流的作用,第二个版本的缓存逻辑不符合需求:

现有代码的问题

  1. 第一个版本:无论是否处于节流等待状态,都会先执行原函数func,这直接违背了节流的核心——等待期内不执行原函数,相当于只做了延迟解锁,根本没节流。
  2. 第二个版本:用参数作为key缓存结果,但你的需求是「节流等待时返回最后一次计算的结果」,而不是「相同参数返回缓存」。如果等待期内传入新的参数,cache[key]会是undefined,自然无法得到正确结果。

修正后的实现

我们只需要保存上一次执行原函数的结果,不需要按参数缓存。当处于节流等待状态时,直接返回这个结果;非等待状态则执行原函数、更新结果并启动节流定时器:

_.throttle = function (func, wait) {
  let isThrottled = false;
  let lastResult; // 只保存最后一次执行的结果

  return function (...args) {
    // 处于节流状态,直接返回上一次结果
    if (isThrottled) {
      return lastResult;
    }

    // 非节流状态,执行原函数并保存结果
    lastResult = func.apply(this, args);
    isThrottled = true;

    // 等待时间后解锁节流
    setTimeout(() => {
      isThrottled = false;
    }, wait);

    // 返回本次执行的结果
    return lastResult;
  };
};

逻辑说明

  • isThrottled:标记当前是否处于节流等待期
  • lastResult:存储上一次执行原函数得到的结果
  • 当调用节流后的函数时:
    • 如果在等待期,直接返回lastResult,不执行原函数
    • 如果不在等待期,执行原函数,更新lastResult,然后启动定时器锁定节流状态
  • 定时器到期后,解锁节流状态,允许下一次调用执行原函数

测试验证

用你提到的字符串反转函数测试:

const reverseStr = (str) => str.split('').reverse().join('');
const throttledReverse = _.throttle(reverseStr, 2000);

console.log(throttledReverse('abc')); // 输出 'cba',执行原函数
console.log(throttledReverse('def')); // 输出 'cba',处于节流等待,返回上一次结果
setTimeout(() => console.log(throttledReverse('ghi')), 2500); // 输出 'ihg',节流到期,执行原函数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:35:10