在Javascript中缓存和预取即将到期的承诺

时间:2014-10-21 11:32:21

标签: javascript node.js promise memoization bluebird

Promise是我在Javascript中管理异步代码的首选方式。 Memoize(memoizee on npm)是一个用于轻松缓存的Javascript库。预取函数的结果。

理想情况下,我希望将两者中的优点结合起来,并且能够“过期”Promise并预先获取新的Promise结果(当缓存被触及并接近到期时)。 Memoize可以做到这一点,但它并没有考虑到Promise。

(我知道Promises有一个内置的“永远缓存”,就其本质而言,但永远对我的应用来说太长了)

到目前为止,我做到这一点的最佳尝试如下(使用bluebirdmemoizeunderscore的node.js示例):

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));
};

这个函数将允许我记忆异步函数(具有类似节点的回调)返回一个promise,同时还提供Memoize库提供的所有缓存到期(+更多)功能。

然而,这种方法对我来说似乎很乱并且过度设计。我想我自己 - 这肯定是一个常见的问题,而其他人已经提出了更优雅的解决方案吗?

这是我尝试做的最佳方法吗?还有另一个像memoize这样专门为promises设计的库吗?我错过了一个更简单的解决方案吗?

任何指导都将不胜感激。

2 个答案:

答案 0 :(得分:1)

  

这个函数允许我记忆一个异步函数(带有类似节点的回调)返回一个promise。然而,这种方法对我来说似乎很乱并且过度设计。

是的 - 你已经有一个函数返回一个promise,没有理由回到nodebacks。

  

我错过了一个更简单的解决方案吗?

返回promise的函数只是一个返回某个值的函数 - 一个可以由memoize函数缓存的值。只需做

memoize(funcReturningPromise, options)

答案 1 :(得分:0)

您正确理解承诺 - 承诺是价值的代理 - 一旦设定它就永远不会改变。

唯一的方式是每次都不返回相同的承诺 - 您每次都必须返回不同的承诺(就像您的示例一样)。最简单的解决方案是使用memoize承诺返回函数(并且它将 promise 缓存为值)。

如果我们有function foo(){返回承诺。只有memoize才能自行运行,然后使用图书馆提供的所有工具。

注意:promisify价格昂贵且功能非常快 - 您真的不想在运行时调用它。您只需在代码中返回new Promise即可。