键入脚本
用于 Typescript 的纪念装饰.
安装
npm install --save typescript-memoize
用法 :
@Memoize(hashFunction?: (...args: any[]) => any)
可以用几种方式: 使用时
- 纪念一个
get访问者, - 纪念一种不需要参数的方法,
- 仅根据第一个参数而有所不同的方法,
- 纪念根据参数组合而有所不同的方法
- 使用具有深等比较( 默认) 的物体来纪念方法
你可以叫回忆方法 在内部 同样的阶级,太。 如果您想要记住整个数据集的返回值, 以及同一数据集经过过滤或映射的版本, 这可能会有用 .
纪念一个 get 访问器,或不需要参数的方法
两者都一样 之后呼吁采用没有参数的纪念方法,或 get 访问器,总是返回相同的值.
我一般都认为这是反模式的 呼唤 get 启动昂贵操作的接入器 简单添加 Memoize() 改为 get 允许无缝的懒惰装入.
import {Memoize,MemoizeExpiring} from 'typescript-memoize';
class SimpleFoo {
// Memoize a method without parameters
@Memoize()
public getAllTheData() {
// do some expensive operation to get data
return data;
}
// Memoize a method and expire the value after some time in milliseconds
@MemoizeExpiring(5000)
public getDataForSomeTime() {
// do some expensive operation to get data
return data;
}
// Memoize a getter
@Memoize()
public get someValue() {
// do some expensive operation to calculate value
return value;
}
}
然后我们从别的地方叫他们 我们的代码:
let simpleFoo = new SimpleFoo();
// Memoizes a calculated value and returns it:
let methodVal1 = simpleFoo.getAllTheData();
// Returns memoized value
let methodVal2 = simpleFoo.getAllTheData();
// Memoizes (lazy-loads) a calculated value and returns it:
let getterVal1 = simpleFoo.someValue;
// Returns memoized value
let getterVal2 = simpleFoo.someValue;
仅根据第一个参数而变化的方法
之后对这种被纪念的方法风格的呼唤,总是会回归同样的价值.
我不知道为什么有人会用这种方法 来纪念一个方法 更多 而不是一个参数, 但这是可能的.
import {Memoize} from 'typescript-memoize';
class ComplicatedFoo {
// Memoize a method without parameters (just like the first example)
@Memoize()
public getAllTheData() {
// do some expensive operation to get data
return data;
}
// Memoize a method with one parameter
@Memoize()
public getSomeOfTheData(id: number) {
let allTheData = this.getAllTheData(); // if you want to!
// do some expensive operation to get data
return data;
}
// Memoize a method with multiple parameters
// Only the first parameter will be used for memoization
@Memoize()
public getGreeting(name: string, planet: string) {
return 'Hello, ' + name + '! Welcome to ' + planet;
}
}
我们称这些方法来自我们代码的其他地方:
let complicatedFoo = new ComplicatedFoo();
// Returns calculated value and memoizes it:
let oneParam1 = complicatedFoo.getSomeOfTheData();
// Returns memoized value
let oneParam2 = complicatedFoo.getSomeOfTheData();
// Memoizes a calculated value and returns it:
// 'Hello, Darryl! Welcome to Earth'
let greeterVal1 = complicatedFoo.getGreeting('Darryl', 'Earth');
// Ignores the second parameter, and returns memoized value
// 'Hello, Darryl! Welcome to Earth'
let greeterVal2 = complicatedFoo.getGreeting('Darryl', 'Mars');
纪念根据参数组合而有所不同的方法
传入 hashFunction 它使用与您的目标方法相同的参数,以记忆基于所有参数的值,或者其他一些自定义逻辑
import {Memoize} from 'typescript-memoize';
class MoreComplicatedFoo {
// Memoize a method with multiple parameters
// Memoize will remember values based on keys like: 'name;planet'
@Memoize((name: string, planet: string) => {
return name + ';' + planet;
})
public getBetterGreeting(name: string, planet: string) {
return 'Hello, ' + name + '! Welcome to ' + planet;
}
// Memoize based on some other logic
@Memoize(() => {
return new Date();
})
public memoryLeak(greeting: string) {
return greeting + '!!!!!';
}
// Memoize also accepts parameters via a single object argument
@Memoize({
expiring: 10000, // milliseconds
hashFunction: (name: string, planet: string) => {
return name + ';' + planet;
}
})
public getSameBetterGreeting(name: string, planet: string) {
return 'Hello, ' + name + '! Welcome to ' + planet;
}
}
我们把这些方法叫做我们代码中的别处 现在你应该得到这个想法:
let moreComplicatedFoo = new MoreComplicatedFoo();
// 'Hello, Darryl! Welcome to Earth'
let greeterVal1 = moreComplicatedFoo.getBetterGreeting('Darryl', 'Earth');
// 'Hello, Darryl! Welcome to Mars'
let greeterVal2 = moreComplicatedFoo.getBetterGreeting('Darryl', 'Mars');
// Fill up the computer with useless greetings:
let greeting = moreComplicatedFoo.memoryLeak('Hello');
提醒接受一个或多个允许缓存在命令上无效的“ tag”字符串
通过一个带有一个或多个“ tag”字符串的数组,这些字符串将允许您日后清除与方法或方法相关的缓存结果 get使用 clear() 函数.
这个 clear() 函数还需要一系列“tag”字符串.
import {Memoize} from 'typescript-memoize';
class ClearableFoo {
// Memoize accepts tags
@Memoize({ tags: ["foo", "bar"] })
public getClearableGreeting(name: string, planet: string) {
return 'Hello, ' + name + '! Welcome to ' + planet;
}
// Memoize accepts tags
@Memoize({ tags: ["bar"] })
public getClearableSum(a: number, b: number) {
return a + b;
}
}
我们把这些方法叫做我们代码中的别处.
import {clear} from 'typescript-memoize';
let clearableFoo = new ClearableFoo();
// 'Hello, Darryl! Welcome to Earth'
let greeterVal1 = clearableFoo.getClearableGreeting('Darryl', 'Earth');
// Ignores the second parameter, and returns memoized value
// 'Hello, Darryl! Welcome to Earth'
let greeterVal2 = clearableFoo.getClearableGreeting('Darryl', 'Mars');
// '3'
let sum1 = clearableFoo.getClearableSum(2, 1);
// Ignores the second parameter, and returns memoized value
// '3'
let sum2 = clearableFoo.getClearableSum(2, 2);
clear(["foo"]);
// The memoized values are cleared, return a new value
// 'Hello, Darryl! Welcome to Mars'
let greeterVal3 = clearableFoo.getClearableGreeting('Darryl', 'Mars');
// The memoized value is not associated with 'foo' tag, returns memoized value
// '3'
let sum3 = clearableFoo.getClearableSum(2, 2);
clear(["bar"]);
// The memoized values are cleared, return a new value
// 'Hello, Darryl! Welcome to Earth'
let greeterVal4 = clearableFoo.getClearableGreeting('Darryl', 'Earth');
// The memoized values are cleared, return a new value
// '4'
let sum4 = clearableFoo.getClearableSum(2, 2);
用深刻的平等比较来纪念
默认情况下,记忆化现在在比较对象时使用深度平等,这对结构相同但引用不同的对象和阵列有用. 如果需要,您可以禁用与 useDeepEqual: false 选项 :
import {Memoize} from 'typescript-memoize';
class DeepEqualityFoo {
// Uses deep equality comparison by default
@Memoize()
public processObject(obj: any) {
// This will only be called once for objects with the same structure,
// even if they are different instances
return expensiveOperation(obj);
}
// Disable deep equality if you want reference equality instead
@Memoize({
useDeepEqual: false
})
public processObjectWithReferenceEquality(obj: any) {
// This will be called for each new object reference,
// even if they have the same structure
return expensiveOperation(obj);
}
// Combine with other options
@Memoize({
expiring: 5000, // expire after 5 seconds
tags: ["objects"]
})
public processComplexObject(obj: any) {
return expensiveOperation(obj);
}
}
我们可以称之为这些方法,并在深刻平等的基础上获得纪念成果:
let deepFoo = new DeepEqualityFoo();
// First call with an object
const result1 = deepFoo.processObject({ id: 123, name: "Test" });
// Second call with different object instance but same structure
// Will return the memoized result without calling the original method again
const result2 = deepFoo.processObject({ id: 123, name: "Test" });
// Call with different object structure
// Will call the original method again
const result3 = deepFoo.processObject({ id: 456, name: "Different" });
// Deep equality works with complex nested objects too
const result4 = deepFoo.processComplexObject({
user: {
id: 123,
details: {
age: 30,
preferences: ["red", "blue"]
}
}
});
// Using reference equality will call the method for each new object
const refObj = { id: 123, name: "Test" };
const result5 = deepFoo.processObjectWithReferenceEquality(refObj);
// This will be memoized since it's the same reference
const result6 = deepFoo.processObjectWithReferenceEquality(refObj);
// This will call the method again since it's a new reference
const result7 = deepFoo.processObjectWithReferenceEquality({ id: 123, name: "Test" });
深度平等比较采用 快速深度平等 高效的深度平等比较软件包.