Node.js 如何缓存要在异步NodeJS调用内部使用的外部作用域值?

Node.js 如何缓存要在异步NodeJS调用内部使用的外部作用域值?,node.js,caching,asynchronous,redis,Node.js,Caching,Asynchronous,Redis,下面的代码说明了我的意图,如果你能想象一个天真的程序员第一次可能会尝试写这个: function (redisUpdatesHash) { var redisKeys = Object.keys(redisUpdatesHash); for (var i = 0; i < redisKeys.length; i++) { var key = redisKeys[i]; redisClient.get(key, function (err, value) {

下面的代码说明了我的意图,如果你能想象一个天真的程序员第一次可能会尝试写这个:

function (redisUpdatesHash) {
  var redisKeys = Object.keys(redisUpdatesHash);
  for (var i = 0; i < redisKeys.length; i++) {
    var key = redisKeys[i];
    redisClient.get(key, function (err, value) {
      if (value != redisUpdatesHash[key]) {
        redisClient.set(key, redisUpdatesHash[key]);
        redisClient.publish(key + "/notifications", redisUpdatesHash[key]);
      }
    });
  }
}
函数(redisUpdatesHash){
var redisKeys=Object.keys(redisUpdatesHash);
对于(var i=0;i
问题是,可以预见的是,key是node_redis回调的异步性质的回调作用域中的错误值。由于安全限制超出了我的控制范围,所以检测方法非常原始——因此我唯一的选择就是轮询源的状态。因此,上面的意图是将该状态存储在Redis中,以便我可以在下次轮询期间进行比较,以确定它是否发生了更改。如果有,我发布一个事件并存储新值,以更新下一个轮询周期的比较值


在NodeJS中似乎没有好的方法来实现这一点。。。我愿意接受任何建议-无论是修复上述代码以某种方式执行此检查,还是建议完全执行此检查的不同方法。

我通过使用函数curry在闭包中缓存外部值来解决此问题

在普通Javascript/NodeJS中

asyncCallback = function (newValue, redisKey, redisValue) {
  if (newValue != redisValue) {
    redisClient.set(redisKey, newValue, handleRedisError);
    redisClient.publish(redisKey + '/notifier', newValue, handleRedisError);
  } 
};

curriedAsyncCallback = function (newValue) {
  return function (redisKey) {
    return function (redisValue) {
      asyncCallback(newValue, redisKey, redisValue);
    };
  }; 
};

var newResults = getNewResults(),
    redisKeys = Object.keys(newResults);

for (var i = 0; i < redisKeys.length; i++) {
  redisClient.get(redisKeys[i], curriedAsyncCallback(newResults[redisKeys[i]])(redisKeys[i]));
}

我通过在HighlandJS中使用curry函数找到了实现这一点的方法。不过,我更希望看到如何在vanilla节点中实现这一点。我马上发布我的高地解决方案。
var _ = require('highland'),
    //...

asyncCallback = function (newValue, redisKey, redisValue) {
  if (newValue != redisValue) {
    redisClient.set(redisKey, newValue, handleRedisError);
    redisClient.publish(redisKey + '/notifier', newValue, handleRedisError);
  } 
};

var newResults = getNewResults(),
    redisKeys = Object.keys(newResults),
    curriedAsyncCallback = _.curry(asyncCallback),
    redisGet = _(redisClient.get.bind(redisClient));

redisKeys.each(function (key) {
  redisGet(key).each(curriedAsyncCallback(newResults[key], key));
});