Yuri Astrakhan
Yuri Astrakhan

Reputation: 9965

Combine multiple debounce promises in JS

I would like to optimize multiple expensive server calls by repeatedly calling a function that takes a key, and returns a promise of an object. When resolved, the object is guaranteed to contain the needed key + some value, and it could contain other unrelated keys. The function would:

Are there any NPM libs that would help with this, or should I write it from scratch?

Upvotes: 0

Views: 937

Answers (1)

traktor
traktor

Reputation: 19301

Searching for "NPM consolidate server requests using a single promise" or "... accumulate server requests... " didn't turn up anything obvious. I'll share the mockup code using ES6 promises mentioned in comment to perhaps form the basis of a solution in the absence of other suggestions. As is, not guaranteed etc...

/*******  application code  ********/

function requestKeys( keyArray) {
    // promise an oject for values of keys in keyArray:
    // use asynchronous code to get values for keys in keyArray,
    // return a promise for the parsed result object.
    // ...
}

const latency = 100; // maximum latency between getting a key and making a request

/********  generic code *********/

var getKey = (( requestKeys, latency) => {
    // return a function to return a promise of a key value object
    var promise = null;
    var resolve = null;
    var reject = null;
    var pendingKeys = null;

    var defer = () => {
        promise = new Promise( (r,j) => {resolve = r; reject = j});
        pendingKeys = [];
    };

    var running = false;
    var timesUp = () => {
        resolve( requestKeys( pendingKeys));
        running = false;
    }
    var addKey = ( key) => {
        if(! running) {
            defer();
            setTimeout( timesUp, latency);
            running = true;
        }
        pendingKeys.push( key);
        return promise;
    }
    return addKey;
})( requestKeys, latency);


/*******   test code   *******/

// redefine requestKeys to promise an object with key strings as key values,
// resolve the return promise synchronously for testing:

function requestKeys( keyArray) {
    var keyObj = keyArray.reduce( ((obj, v) => ((obj[v] = v), obj) ), {} );
    return new Promise( (resolve, reject) => resolve(keyObj) );
}

var log = obj => console.log( JSON.stringify(obj));

// get two keys quickly
getKey("holas").then( log);
getKey("buono").then( log);

// wait and get another
setTimeout( function(){getKey('later').then( log)}, 500);

Upvotes: 1

Related Questions