JavaScript 函数防多次调用包装器

问题描述

实现一个名为 once 的高阶函数,接受一个参数 fn,该参数是一个任意参数和返回值类型的函数。once 函数应返回一个新的函数,新函数在首次调用时执行并返回 fn 的结果,之后的所有调用均返回 undefined

示例

示例 1

        
markdown
123456789101112
输入: fn = (a, b, c) => (a + b + c), calls = [[1, 2, 3], [2, 3, 6]] 输出: [{"calls": 1, "value": 6}] 解释: ```typescript const onceFn = once(fn); onceFn(1, 2, 3); // 返回 6 onceFn(2, 3, 6); // 返回 undefined,fn 没有被调用

示例 2

        
markdown
12345678910111213
输入: fn = (a, b, c) => (a * b * c), calls = [[5, 7, 4], [2, 3, 6], [4, 6, 8]] 输出: [{"calls": 1, "value": 140}] 解释: ```typescript const onceFn = once(fn); onceFn(5, 7, 4); // 返回 140 onceFn(2, 3, 6); // 返回 undefined,fn 没有被调用 onceFn(4, 6, 8); // 返回 undefined,fn 没有被调用

约束条件

  • 1 <= calls.length <= 10
  • 1 <= calls[i].length <= 100
  • 2 <= JSON.stringify(calls).length <= 1000

解决方案

        
TypeScript
123456789101112131415
function once<T extends (...args: any[]) => any>(fn: T): ((...args: Parameters<T>) => ReturnType<T> | undefined) { let flag = false; return function (...args: Parameters<T>): ReturnType<T> | undefined { return flag ? undefined : ((flag = true), fn(...args)); }; } /** * 示例用法: * let fn = (a, b, c) => (a + b + c) * let onceFn = once(fn) * * onceFn(1, 2, 3); // 返回 6 * onceFn(2, 3, 6); // 返回 undefined,fn 不会被再次调用 */