每个框架的函数存储器
记忆? - JavaScript 函数的轻量级记忆 (1.3KB)
使用相同参数执行的函数的缓存机制(memoizer)(仅 1.3 KB)
该项目提供了 memoize 函数,通过缓存昂贵的函数调用结果来提高 JavaScript 或 TypeScript 项目的性能。通过记忆,使用相同参数重复调用将返回缓存的结果,从而加快执行速度。
这个模块的工作原理类似于 React 的 useMemo hook,但不需要 React。您可以使用任何框架或纯 javascript 项目
特征
- 函数记忆:缓存具有相同参数的函数调用结果。
- 依赖项跟踪:如果依赖项发生变化,则更新缓存。
- 灵活性:可用于 JavaScript 和 TypeScript 项目。
- CPU密集型运算或复杂计算的最佳解决方案
- 断开连接的函数将从内存中删除。属于该函数的缓存也会被删除。
- 基于WeakMap的缓存存储
- WeakMap 断开无法与弱引用链接通信的方法,并触发垃圾收集器启动
我们为什么要使用memofy?
使用 Memofy,您可以将函数的执行时间减少多达 1500 倍。以下结果是通过重函数测试得到的。 ??
| Test Case | Function Execute Time (ms) |
|---|---|
| With Memofy (CACHED) | 0.083 ms |
| Without Memofy | 57.571 ms |
没有 Memofy
import memofy from "memofy";
const dep1 = /** Variable to track change */
const heavyMethod = memofy((arg1, arg2, ...args) => {
// calculate something then return
}, [dep1, dep2, ...deps]);
// heavyMethod looks at the deps and arguments every time it is called.
// If there is no change, it brings it from the cache. If there is a change, it runs the function again
而且非常简单安装
npm install memofy
国家公共管理
yarn add memofy
纱
使用案例
没有 deps 参数
import memofy from "memofy";
const concatPhoneNumber = (extension, number) => {
// Heavy calculation
// return result
};
const memoizedConcatPhoneNumber = memofy(concatPhoneNumber, []);
memoizedConcatPhoneNumber(90, 555); // Runs concatPhoneNumber once
memoizedConcatPhoneNumber(90, 555); // Don't run because fetched from cache (same parameter)
memoizedConcatPhoneNumber(90, 552); // Runs concatPhoneNumber because params is changed
带 deps 参数
import memofy from "memofy";
const product = { title: "Test product", price: 10 };
const calculateTax = (taxRatio) => {
// Calculate tax by product price
// Heavy calculation
return taxRatio * product.price;
};
const memoizedCalculateTax = memofy(calculateTax, [product]);
calculateTax(2); // Runs calculateTax when first run -> 20
calculateTax(2); // // Don't run because fetched from cache (same parameter and same deps) -> 20
product.price = 40;
calculateTax(3); // Runs calculateTax because product dep changed -> 120
import memofy from "memofy";
const products = [
/**Let's say there are more than 100 products */
];
// It is costly to cycle through 100 products each time. Just keep the result in the cache when it runs once.
const getTotalPrice = (fixPrice) => {
return products.reduce((acc, curr) => acc + curr.price, 0);
};
const _getTotalPrice = memofy(getTotalPrice, [products]);
getTotalPrice(0); // Runs getTotalPrice once
getTotalPrice(0); // Don't run because fetched from cache
products.push({
/** a few products */
});
getTotalPrice(2); // Runs again getTotalPrice because products and parameter changed
有上下文
import memofy from "memofy";
this.user.name = "Jack"; // For example inject name to context
const getName = (suffix) => {
return `${suffix} ${this.user.name}`;
};
const memoizedGetName = memofy(getName, [], this);
memoizedGetName("Mr"); // Result is Mr Jack
this.user.name = "John";
memoizedGetName("Mr"); // Result is Mr John because context data changed
type Args = Array<any>; type Deps = Readonly<Array<any>>; type MemoizedFunction<A extends Args, ReturnType> = (...args: A) => ReturnType; declare function memofy<A extends Args, ReturnType extends any>( _functionToMemoize: (...args: Array<unknown>) => ReturnType, _deps?: Deps, _context?: unknown ): MemoizedFunction<A, ReturnType>;
打字稿声明
绩效结果
| Case | ms |
|---|---|
| First execute time (no caching) | > 52.08 ms |
| Second execute time (caching) | < 0.03 ms |
| and subsequent execution (caching) | < 0.03 ms |
测试覆盖率结果
| File | % Stmts | % Branch | % Funcs | % Lines |
|---|---|---|---|---|
| All files | 90.69 | 86.95 | 100 | 94.59 |
| lib | 88.88 | 92.3 | 100 | 87.5 |
| index.ts | 88.88 | 92.3 | 100 | 87.5 |
| lib/store | 92 | 80 | 100 | 100 |
| DependencyCacheStore.ts.ts | 90 | 75 | 100 | 100 |
| FunctionCacheStore.ts | 93.33 | 83.33 | 100 | 100 |
贡献
以上是每个框架的函数存储器的详细内容。更多信息请关注PHP中文网其他相关文章!
热AI工具
Undress AI Tool
免费脱衣服图片
Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片
AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。
Clothoff.io
AI脱衣机
Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!
热门文章
热工具
记事本++7.3.1
好用且免费的代码编辑器
SublimeText3汉化版
中文版,非常好用
禅工作室 13.0.1
功能强大的PHP集成开发环境
Dreamweaver CS6
视觉化网页开发工具
SublimeText3 Mac版
神级代码编辑软件(SublimeText3)
热门话题
如何在JS中与日期和时间合作?
Jul 01, 2025 am 01:27 AM
JavaScript中的日期和时间处理需注意以下几点:1.创建Date对象有多种方式,推荐使用ISO格式字符串以保证兼容性;2.获取和设置时间信息可用get和set方法,注意月份从0开始;3.手动格式化日期需拼接字符串,也可使用第三方库;4.处理时区问题建议使用支持时区的库,如Luxon。掌握这些要点能有效避免常见错误。
为什么要将标签放在的底部?
Jul 02, 2025 am 01:22 AM
PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl
什么是在DOM中冒泡和捕获的事件?
Jul 02, 2025 am 01:19 AM
事件捕获和冒泡是DOM中事件传播的两个阶段,捕获是从顶层向下到目标元素,冒泡是从目标元素向上传播到顶层。1.事件捕获通过addEventListener的useCapture参数设为true实现;2.事件冒泡是默认行为,useCapture设为false或省略;3.可使用event.stopPropagation()阻止事件传播;4.冒泡支持事件委托,提高动态内容处理效率;5.捕获可用于提前拦截事件,如日志记录或错误处理。了解这两个阶段有助于精确控制JavaScript响应用户操作的时机和方式。
如何减少JavaScript应用程序的有效载荷大小?
Jun 26, 2025 am 12:54 AM
如果JavaScript应用加载慢、性能差,问题往往出在payload太大,解决方法包括:1.使用代码拆分(CodeSplitting),通过React.lazy()或构建工具将大bundle拆分为多个小文件,按需加载以减少首次下载量;2.移除未使用的代码(TreeShaking),利用ES6模块机制清除“死代码”,确保引入的库支持该特性;3.压缩和合并资源文件,启用Gzip/Brotli和Terser压缩JS,合理合并文件并优化静态资源;4.替换重型依赖,选用轻量级库如day.js、fetch
JavaScript模块上的确定JS综述:ES模块与COMPORJS
Jul 02, 2025 am 01:28 AM
ES模块和CommonJS的主要区别在于加载方式和使用场景。1.CommonJS是同步加载,适用于Node.js服务器端环境;2.ES模块是异步加载,适用于浏览器等网络环境;3.语法上,ES模块使用import/export,且必须位于顶层作用域,而CommonJS使用require/module.exports,可在运行时动态调用;4.CommonJS广泛用于旧版Node.js及依赖它的库如Express,ES模块则适用于现代前端框架和Node.jsv14 ;5.虽然可混合使用,但容易引发问题
如何在node.js中提出HTTP请求?
Jul 13, 2025 am 02:18 AM
在Node.js中发起HTTP请求有三种常用方式:使用内置模块、axios和node-fetch。1.使用内置的http/https模块无需依赖,适合基础场景,但需手动处理数据拼接和错误监听,例如用https.get()获取数据或通过.write()发送POST请求;2.axios是基于Promise的第三方库,语法简洁且功能强大,支持async/await、自动JSON转换、拦截器等,推荐用于简化异步请求操作;3.node-fetch提供类似浏览器fetch的风格,基于Promise且语法简单
垃圾收集如何在JavaScript中起作用?
Jul 04, 2025 am 12:42 AM
JavaScript的垃圾回收机制通过标记-清除算法自动管理内存,以减少内存泄漏风险。引擎从根对象出发遍历并标记活跃对象,未被标记的则被视为垃圾并被清除。例如,当对象不再被引用(如将变量设为null),它将在下一轮回收中被释放。常见的内存泄漏原因包括:①未清除的定时器或事件监听器;②闭包中对外部变量的引用;③全局变量持续持有大量数据。V8引擎通过分代回收、增量标记、并行/并发回收等策略优化回收效率,降低主线程阻塞时间。开发时应避免不必要的全局引用、及时解除对象关联,以提升性能与稳定性。
var vs Let vs const:快速JS综述解释器
Jul 02, 2025 am 01:18 AM
var、let和const的区别在于作用域、提升和重复声明。1.var是函数作用域,存在变量提升,允许重复声明;2.let是块级作用域,存在暂时性死区,不允许重复声明;3.const也是块级作用域,必须立即赋值,不可重新赋值,但可修改引用类型的内部值。优先使用const,需改变变量时用let,避免使用var。


