Caching and pre-fetching expiring promises in Javascript

给你一囗甜甜゛ 提交于 2019-12-10 04:04:53

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!