I'd like to debounce the render function for each call to a specific page - rendering a different page would debounce separately. The memoize function should do the trick, but it's not working correctly.
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);
};
any ideas? /
I'd like to debounce the render function for each call to a specific page - rendering a different page would debounce separately. The memoize function should do the trick, but it's not working correctly.
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);
};
any ideas? http://jsfiddle/Zq8Wd/1/
Share Improve this question edited Dec 23, 2013 at 15:36 michael asked Dec 23, 2013 at 15:30 michaelmichael 4,5478 gold badges50 silver badges75 bronze badges 3- 1 What's "not working correctly"? What does this code do pared to what you want it to do? – gen_Eric Commented Dec 23, 2013 at 15:33
- the alt version debounces correctly, the memoized version passes every call through. it should wait 1000ms before allowing the subsequent call to render the same page – michael Commented Dec 24, 2013 at 17:45
- Just wrote gist for memoized async debounced function based on arg, could be useful gist.github./nzvtrk/1a444cdf6a86a5a6e6d6a34f0db19065 – Artur Khrabrov Commented Dec 2, 2019 at 16:11
2 Answers
Reset to default 5The problem with using _.memoize()
this way is that it caches return values, not side-effects. If you wanted to use _.memoize()
for this problem, you'd probably have to do something like this:
rp = _.memoize(function (pageNo) {
return _.debounce(function () {
document.getElementById("underscore").innerHTML +=
'<br />' + pageNo + '@' + new Date().getTime();
}, 1000, true);
});
rp(1)();
rp(2)();
Updated JSFiddle.
I just came up with this:
/**
* 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 puted, 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;
};
}
It always returns a Promise
so you can just wait for it to resolve, and ignore any rejections which means the value was debounced/not puted.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745588449a4634686.html
评论列表(0条)