最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

javascript - using _.memoize() with _.debounce() - Stack Overflow

matteradmin7PV0评论

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
Add a ment  | 

2 Answers 2

Reset to default 5

The 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.

Post a comment

comment list (0)

  1. No comments so far