我想去除每个特定页面调用的渲染功能 - 渲染不同的页面会分别去抖动。 memoize函数应该可以解决问题,但它无法正常工作。
var renderPage_underscore = function(pageNo){
var debouncer = _.memoize(
// memoize function
_.debounce(
// debounced function
function () {
// Do renderPage() work here
document.getElementById("underscore").innerHTML +=
'<br />' + pageNo + '@' + new Date().getTime();
},
1000, // delay
true
),
// memoize hash function
function (pageNo) {
return pageNo;
}
);
return debouncer(pageNo);
};
答案 0 :(得分:2)
以这种方式使用_.memoize()
的问题在于它缓存返回值,而不是副作用。如果您想使用_.memoize()
来解决此问题,您可能需要执行以下操作:
rp = _.memoize(function (pageNo) {
return _.debounce(function () {
document.getElementById("underscore").innerHTML +=
'<br />' + pageNo + '@' + new Date().getTime();
}, 1000, true);
});
rp(1)();
rp(2)();
更新了JSFiddle。
答案 1 :(得分:0)
我想出了这个:
/**
* Memoizes and debounces a function. i.e., returns a new function, that when invoked,
* returns a Promise that will resolve after `delay` ms unless invoked repeatedly,
* in which case the last promise will be rejected and the delay will be reset. If the
* result has already been computed, will resolve instantly.
*
* @param {Function} func Function to memoize+debounce
* @param {Number} delay Delay in milliseconds
* @param {Function} serialize Function used to resolve the cache key
* @return {Function} Memoized+debounced function.
*/
function membounce(func, delay=333, serialize = x => x) {
let cache = new Map();
let timer, cancel, lastKey;
return (...args) => {
let key = serialize.call(func, ...args);
if(timer) {
clearTimeout(timer);
cancel(new Error('Debounced'));
cache.delete(lastKey);
}
if(cache.has(key)) {
return cache.get(key);
}
let promise = new Promise((resolve,reject) => {
cancel = reject;
timer = setTimeout(() => {
let result = func(...args);
resolve(result);
timer = null;
}, delay);
});
cache.set(key, promise);
lastKey = key;
return promise;
};
}
总是返回Promise
,因此您可以等待它解决,并忽略任何拒绝,这意味着该值已被去抖动/未计算。