
es-toolkit once 函数完全指南限制函数仅执行一次并缓存结果【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkitonce是 es-toolkit 中用于限制函数只执行一次的实用函数首次调用时真正执行并缓存返回值后续所有调用直接返回缓存结果。它在es-toolkit/compat兼容层中与 Lodash 保持 1:1 的行为对齐适用于初始化逻辑、事件绑定、数据库连接、API Token 获取等只需执行一次的昂贵操作。读完本文你将掌握once的调用方式、返回值语义、源码级实现原理及其与主库版本的差异。背景es-toolkit/compat 兼容层once的兼容版本位于es-toolkit/compat模块下该模块镜像了 Lodash 的接口和行为目标是让现有 Lodash 代码库无需改写调用点即可直接迁移到 es-toolkit。根据 compat 模块介绍推荐的迁移路径是先将lodash/lodash-es的导入路径替换为es-toolkit/compat再逐步清理调用点、切换到严格类型的es-toolkit主入口。本文讲解的 onceLodash 兼容版 在功能上与主库的 once 完全一致兼容层只是为其提供了与 Lodash 相同的导入入口。基本用法once接收一个函数返回一个只能被调用一次的新函数const limitedFunc once(func);第一次调用时执行原函数之后每次调用都不会再执行原函数而是直接返回第一次调用的结果。once(func)使用once限制函数仅调用一次。首次调用后结果被缓存后续调用返回相同的值。import { once } from es-toolkit/compat; // 基础用法 let count 0; const increment once(() { count; console.log(Counter incremented:, count); return count; }); increment(); // 输出 Counter incremented: 1返回 1 increment(); // 无输出返回 1 increment(); // 无输出返回 1初始化函数实战示例once特别适合创建昂贵的初始化操作或 setup 函数例如数据库连接、API Token 初始化等import { once } from es-toolkit/compat; // 实用示例 - 初始化函数 const initialize once(() { console.log(Initializing application...); // 昂贵的初始化操作 return Initialization complete; }); // 即使多次调用初始化也只会执行一次 initialize(); // 输出 Initializing application... initialize(); // 无输出注意上例中两次调用返回的都是Initialization complete——即使初始化逻辑未被再次执行缓存的结果也会被原样返回保证调用方拿到的数据一致。带参数与异步场景从 主库 once 文档 可以看到once同样适用于带参数的函数以及返回 Promise 的异步函数import { once } from es-toolkit/function; // 带参数的函数 const logOnce once((message: string) { console.log(Important message: ${message}); }); logOnce(Hello); // 输出 Important message: Hello logOnce(Hello again); // 无输出已被调用过 logOnce(Hello once more); // 无输出已被调用过 // 异步场景只有第一次调用会真正发起 API 请求 const fetchConfig once(async () { console.log(Fetching configuration); const response await fetch(/api/config); return response.json(); }); const config1 await fetchConfig(); const config2 await fetchConfig(); // 返回缓存结果不发起新请求在异步场景中once缓存的是第一次调用返回的 Promise因此第二次调用拿到的是同一个 Promise不会重复请求。参数与返回值ParametersfuncFunction要限制为仅调用一次的函数。ReturnsFunction返回一个新的受限函数。从第二次调用起返回第一次调用的结果。源码级实现原理主库实现src/function/once.tsonce的核心实现非常简洁位于 src/function/once.tsexport function onceF extends (() any) | ((...args: any[]) void)(func: F): F { let called false; let cache: ReturnTypeF; return function (this: unknown, ...args: ParametersF): ReturnTypeF { if (!called) { called true; cache func.apply(this, args); } return cache; } as F; }实现要点通过闭包维护called标志位和cache缓存变量两个状态都保存在返回的新函数内部互不干扰第一次调用时通过func.apply(this, args)以调用方的this上下文和全部参数执行原函数并将返回值存入cache之后的每次调用跳过执行逻辑直接return cache因此无论传入什么参数返回的都是首次调用的结果返回值类型ReturnTypeF与参数类型ParametersF被完整保留返回的受限函数在 TypeScript 类型上与传入函数一致声明为F保证了类型安全。由于cache直接保存首次调用的返回值once也适用于返回undefined或没有返回值的函数——缓存的是undefined后续调用同样返回undefined。兼容层实现src/compat/function/once.ts兼容版本的实现更加精简它只是对主库实现的直接转发import { once as onceToolkit } from ../../function/once.ts; export function onceT extends (...args: any) any(func: T): T { return onceToolkit(func); }从源码结构看src/compat/function/once.ts 将全部逻辑委托给主库实现自身仅承担导出入口与类型签名适配的职责。这也是 compat 层API 形状与 Lodash 一致、行为完全对齐设计原则的体现。once通过 src/compat/compat.ts 中的export { once } from ./function/once.ts;对外导出同时也可从独立的入口es-toolkit/compat/once导入如import once from es-toolkit/compat/once后者在无 tree-shaking 的环境CommonJSrequire()、React Native、无打包器的 Node.js下只加载所需文件。测试验证行为边界的确认主库测试 src/function/once.spec.ts 与兼容层测试 src/compat/function/once.spec.ts 共同验证了以下关键行为仅调用一次使用vi.fn()包装函数多次调用后断言toHaveBeenCalledTimes(1)且每次返回值相同忽略递归调用在once包装的函数内部再次调用自身最终计数仍为 1说明递归调用不会触发重复执行异常只抛一次如果原函数抛出异常第一次调用抛错后续调用不再抛错因为called已置为true后续直接返回缓存的undefined保留this上下文将once包装的函数作为对象方法调用时this.value能正确取到对象属性证明func.apply(this, args)正确透传了调用上下文支持无返回值函数返回undefined的函数被多次调用时原函数同样只执行一次。这些测试用例覆盖了once的主要边界场景可在迁移或改造时作为行为基准。适用场景与使用建议综合 兼容版文档 与主库 once 文档once最典型的应用场景包括初始化 / setup 函数应用启动时的配置加载、数据库连接池建立、日志系统初始化API Token / 凭据获取网络请求前的一次性鉴权令牌初始化避免重复请求事件处理器确保某个事件回调如按钮点击、路由切换只执行一次惰性单例首次访问时计算结果并缓存后续访问直接复用。需要注意的是once缓存的是首次调用的结果与memoize按参数缓存不同once不区分参数——后续调用即使传入不同参数也只会拿到首次调用的结果。如果需要按参数区分缓存应选用 es-toolkit 的 memoize如果需要在限定次数如 n 次之后触发可参考 after 等兼容函数。从主库的 function 模块索引 可以查看更多相关函数。总结once(func)返回一个受限函数首次调用执行原函数并缓存结果后续调用直接返回缓存值兼容版es-toolkit/compat的once与主库es-toolkit/function的once功能一致前者仅为 Lodash 迁移场景提供入口实现依赖闭包内的called标志与cache缓存通过apply(this, args)完整保留调用上下文测试确认了仅执行一次、忽略递归、异常只抛一次、保留 this、支持无返回值等边界行为可直接作为使用依据。【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考