问题
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.
回答1:
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)
回答2:
You understand promises correctly - a promise is a proxy for a value - once it's set it will never change.
The only way around this is to not return the same promise each time - you'd have to return a different promise each time (like your example does). The simplest solution would be to use memoize
with promise returning functions (and it'd cache the promise for the value).
If we have a function foo(){
that returns a promise. It's perfectly fine to just memoize
that function itself and then use all the tools the library provides.
Note: promisify
is expensive and produces a very fast function - you really don't want to call it at runtime. You could simply return new Promise
in your code.
来源:https://stackoverflow.com/questions/26485662/caching-and-pre-fetching-expiring-promises-in-javascript