Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caching and pre-fetching expiring promises in Javascript

Promises are my preferred way of managing my asynchronous code in Javascript. Memoize (memoizee on npm) is a Javascript library for easily caching & pre-fetching results of functions.

Ideally I want to combine the best of both, and have the ability to "expire" a Promise and pre-fetch a new Promise result (when the cache is touched and near to expiring). Memoize can do this, but it wasn't built with Promises in mind.

(I understand that Promises have a built-in "forever-cache" as is their nature, but forever is too long for my application)

My best attempt to do this so far is as follows (node.js example using bluebird, memoize and underscore):

var memoize = require('memoizee')
  , Promise = require('bluebird')
  , _ = require('underscore')
  ;

// returns a memoized Promise-generating function
function memoizePromiser(funcReturningPromise, options) {
    var opts = _.defaults(options || {}, {async: true});

    return Promise.promisify(memoize(function(){
        var args = _.initial(arguments);
        var cb = _.last(arguments);
        funcReturningPromise.apply(this, args).nodeify(cb);
    }, opts));
};

This function will allow me to memoize an async function (with node-like callbacks) returning a promise, whilst also providing all the cache-expiry (+ more) functionality offered by the Memoize library.

However, this approach seems messy and over-engineered to me. I think to myself - surely this is a common enough problem hat someone else has made a more elegant solution?

Is this the best approach for what I'm trying to do? Is there another library like memoize which is designed specifically for promises? Is there a simpler solution that I've missed?

Any guidance would be appreciated.

like image 280
Mikuso Avatar asked Oct 21 '14 11:10

Mikuso


1 Answers

This function will allow me to memoize an async function (with node-like callbacks) returning a promise. However, this approach seems messy and over-engineered to me.

Yes - you already have a function returning a promise, there is no reason to go back to nodebacks.

Is there a simpler solution that I've missed?

A function that returns a promise is just a function that returns some value - a value that can be cached by the memoize function. Simply do

memoize(funcReturningPromise, options)
like image 56
Bergi Avatar answered Sep 23 '22 10:09

Bergi