原文链接: nodejs 函数缓存库 memoizeOne 和 micro-memoize Memoizee
下一篇: execa 进程库
支持设置缓存数目, 不支持时间缓存, 支持promise
https://github.com/planttheidea/micro-memoize#readme
// const memoizeOne = require('memoize-one')
const isDeepEqual = require('lodash/isequal')
const memoize = require("micro-memoize");
// 返回true则不执行函数, 直接返回上次执行结果
// 接受参数为新旧两个参数的数组
function isEqual(oldArgs, newArgs) {
return isDeepEqual(oldArgs, newArgs)
}
function add(a, b) {
console.log('a+b=', a + b)
return a + b
}
let addCache = memoize(add, {
maxSize: 3,
isEqual: isEqual
})
// 只保存最新的执行参数
addCache(1, 1) // 执行
addCache(1, 1) // 返回缓存
addCache(1, 2) // 执行
addCache(1, 1) // 返回缓存, 前面三个缓存中命中一个
addCache(2, 2) // 执行
addCache(2, 2) // 返回缓存
promise
const fn = async (one: string, two: string) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error({ one, two }));
}, 500);
});
};
const memoized = memoize(fn, { isPromise: true });
memoized("one", "two");
console.log(memoized.cache.snapshot.keys); // [['one', 'two']]
console.log(memoized.cache.snapshot.values); // [Promise]
setTimeout(() => {
console.log(memoized.cache.snapshot.keys); // []
console.log(memoized.cache.snapshot.values); // []
}, 1000);
当设置maxSize为1时的特殊情况
const memoizeOne = require('memoize-one')
const isDeepEqual = require('lodash/isequal')
// 返回true则不执行函数, 直接返回上次执行结果
// 接受参数为新旧两个参数的数组
function isEqual(oldArgs, newArgs) {
return isDeepEqual(oldArgs, newArgs)
}
function add(a, b) {
console.log('a+b=', a + b)
return a + b
}
let addCache = memoizeOne(add, isEqual)
// 只保存最新的执行参数
addCache(1, 1) // 执行
addCache(1, 1) // 返回缓存
addCache(1, 2) // 执行
addCache(1, 1) // 执行, 和上次参数不一致
addCache(2, 2) // 执行
addCache(2, 2) // 返回缓存
支持限制数目,和过期时间, 以及操作缓存, 支持hash比较, 将对象转为hash节省空间, 支持promise和异步
https://github.com/medikoo/memoizee
https://github.com/medikoo/memoizee
memoized = memoize(fn, { maxAge: 1000 }); // 1 second
memoized("foo", 3);
memoized("foo", 3); // Cache hit
setTimeout(function() {
memoized("foo", 3); // No longer in cache, re-executed
memoized("foo", 3); // Cache hit
}, 2000);
memoized = memoize(fn, { max: 2 });
memoized("foo", 3);
memoized("bar", 7);
memoized("foo", 3); // Cache hit
memoized("bar", 7); // Cache hit
memoized("lorem", 11); // Cache cleared for 'foo', 3
memoized("bar", 7); // Cache hit
memoized("foo", 3); // Re-executed, Cache cleared for 'lorem', 11
memoized("lorem", 11); // Re-executed, Cache cleared for 'bar', 7
memoized("foo", 3); // Cache hit
memoized("bar", 7); // Re-executed, Cache cleared for 'lorem', 11
const memoize = require('memoizee')
var mfn = memoize(
function (hash) {
// body of memoized function
console.log('hash', hash)
},
{
normalizer: function (args) {
console.log(args)
// args is arguments object as accessible in memoized function
return JSON.stringify(args[0]);
}
}
);
mfn({foo: "bar"}, {foo: "bar2"});
mfn({foo: "bar"}, {foo: "bar2"}); // Cache hit
mfn({foo: "bar"}, {foo: "bar"}); // Cache hit 因为之比较了第一个参数
var afn = function(a, b) {
return new Promise(function(res) {
res(a + b);
});
};
memoized = memoize(afn, { promise: true });
memoized(3, 7);
memoized(3, 7); // Cache hit
afn = function(a, b, cb) {
setTimeout(function() {
cb(null, a + b);
}, 200);
};
memoized = memoize(afn, { async: true });
memoized(3, 7, function(err, res) {
memoized(3, 7, function(err, res) {
// Cache hit
});
});
memoized(3, 7, function(err, res) {
// Cache hit
});