node.js - 如何将其他参数传递给async.map

时间:2016-10-18 18:27:29

标签: javascript node.js asynchronous

背景资料

我正在尝试编写一些javascript / node.js代码,它们将执行以下操作:

  1. 查询redis数据库并从哈希中获取一堆密钥。这就是redis-cli上的命令:

    127.0.0.1:6379> hkeys小部件:1231231234 1)“13:00:00_17:00:00_mtwrf” 2)“00:00:00_00:00:00” 3)“08:00:00_12:00:00_mtwrf”

  2. 或     127.0.0.1:6379> hkeys小部件:2222222222     1)“00:00:00_00:00:00”

    每个小部件至少有一个密钥...称为默认密钥。默认键如下所示:“00:00:00_00:00:00”

    对于每个HKEYS查询,如果返回的结果不止一个,我需要根据一组匹配条件测试返回的每个键(默认值除外)。无论哪个键匹配,都是用于对redis进行后续HGET的。例如,在上面显示的第一个结果集中......如果键3匹配,我将运行以下命令:

    127.0.0.1:6379> hget widgets:2222222222 08:00:00_12:00:00_mtwrf
    "some value"
    127.0.0.1:6379> 
    

    如果键1或3都不匹配,那么我查询默认键。

    代码

    我最近发现了异步模块。我目前正在我的代码中使用它来循环HKEYS的结果。 请参阅以下代码:

    async.map代码

    router.get('/:widgetnum', function(req, res, next) {
      //validate widgetnum format        
      var widgetnum = req.params.widgetnum;
      if ( !valid_widget(widgetnum) ) {
          var retval = {"res":false, "msg":"malformed widgetnum"};
          res.send(JSON.stringify(retval));
     } else {
          var keys = {};
          redis.hkeys("widgets:" + widgetnum, function(err, data){
              if (err) {
                  res.send(JSON.stringify(false));
              }
              if (data) {
                 current = getCurrentUTC(); // needed by iterator for match criteria. Using a global variable for now.                                 
                async.map(data, hash_iterator, function (err, iterator_results) {
                      if (iterator_results) {
                          console.log("it are: " + iterator_results);
                      }
                      res.send(iterator_results);
                 }); //end async map
              }
    
          }); //end redis.hkeys
      }
    });
    

    问题/问题

    这是有效的,对于HKEYS返回的每个键,我能够运行“hash_iterator”函数。

    但是,一旦进入迭代器函数,在评估/运行每个结果的匹配条件后,我没有运行辅助HGET查询所需的所有信息。

    代码:

      async.map(data, hash_iterator, function (err, iterator_results)
    

    只传递值:

     "13:00:00_17:00:00_mtwrf"
      "00:00:00_00:00:00"
      "08:00:00_12:00:00_mtwrf"
    

    但是我需要哈希名称(在本例中为“widgets:”)和widgetnum来进行HGET调用。

    我想我可以使用全局变量......但我想确保我的方法在这里是正确的。

    任何输入都将不胜感激。

    这是hash_iterator逻辑:

    var hash_iterator = function (redis_key, doneCallBack) {
            var results = {};
            console.log("processing..." + redis_key);
            //skip if default rule....
            if (redis_key.indexOf('00:00:00_00:00:00') == -1){
                    //need to write logic here to do HGET and save 
                    //results somewhere... in case no other keys match 
    
            } else {
                   // run some logic to test match criteria.
                  if (matchfound) {
                            console.log("bingo.  found match in " +  redis_key);
                            redis.hget(hashname + widgetnum + redis_key, function (e, results){
                              if (results) {
                                    return doneCallBack(null, results);
                              } else {
                                     return doneCallBack(null, null);
                              }
    
                           });                           
    
                    }else {
                            console.log ("no match");
                    }
            } 
            return results;
    }
    

1 个答案:

答案 0 :(得分:0)

您可以使用地图以功能样式解决它。只需生成一对数组,然后将其传递给async.map[1,2,3]您可以生成[['key', '1'], ['key', '2'], ['key', 3]]

所以这里的代码是生成对:

redis.hkeys("widgets:" + widgetnum, function(err, data){
    // some code goes here

    var pairs = data.map(function(ts) {
      return [`widgets:${widgetnum}`, ts];
    });

    // async.map call goes here
}); //end redis.hkey

async.map内部迭代器回调中,您可以使用iterator_results[0]

访问密钥

在您的情况下,变量widgetnums 不是全局变量。它只是从较高范围变量,如果你在propper范围内定义它,你可以在嵌套函数中使用它。这是一个非常有用的技巧,叫lexical closure

相关问题