【问题标题】:Async redis & promise异步 redis 和承诺
【发布时间】:2018-07-01 03:29:30
【问题描述】:

我有一个场景,我必须运行一个循环,每次迭代都调用 redis 设置函数(异步),然后我必须关闭与 redis 的连接。

顺序...

  1. 运行 foreach 循环。
  2. 对于每个元素,使用 redis set 命令。
  3. 循环完成后,关闭redis连接。

现在 redis 连接在 for 循环内完成所有设置操作之前关闭。


更多细节...

  • 我正在使用node.js redis client
  • 我知道为什么会发生这种情况,但我不确定如何解决这种情况。
  • 我是 NodeJS 的新手。

【问题讨论】:

    标签: javascript node.js asynchronous redis promise


    【解决方案1】:

    您无需破解结构 - node.js client 支持开箱即用的技术。查看Multi.exec

    命令在Multi 对象中排队,直到Multi.exec()

    // iterate and construct array of set commands
    let commands = items.map(i => ['set', i.key, i.value]);
    
    client
      .multi(commands)
      .exec((err, replies) => {
        // disconnect here
      });
    

    如果您实际上不需要事务,您可以通过client.batch 一次性批处理所有命令。然后,您当然可以相应地围绕此模式组织您的连接和断开策略。

    【讨论】:

      【解决方案2】:

      你可以使用 asyncLoop 来解决这种类型的问题,它在类似的情况下帮助了我很多:-

      var asyncLoop = require('node-async-loop');
      asyncLoop(arr, function (item, next){
        // foreach loop on the array "arr"
        //the each element is "item"
        //call next when the iteration is done
      
       //execute redis command on "item" and then do
       next();
      
      }, function(err)
        if(err==null)
      {
      //do something on loop complete like closing connection etc
      });
      

      这是你可以做你想做的事情的基本方式,你可以不喜欢这样的异步循环:-

      npm install --save node-async-loop
      

      【讨论】:

        【解决方案3】:

        首先你创建一个 promise 数组,然后使用 Promise.all 例如:

        function connectPromise (paramers) {
          return new Promise((resolve, reject) => {
            // if connectToRedisAndSetFunc is a promise
            // conectToRedisAndSetFunc(params).then(data => {
            //  resolve(data)
            //}).catch(err => {
            //  reject(err)
            // })
            conectToRedisAndSetFunc(params, function(err, data) {
              if (err) {
               reject(err)
              } else {
               resolve(data)
              }
            })
          })
        }
        // create promiseArray
        let connectsPromises = params-array.map(p => connectPromise(p))
        
        Promise.All(connectsPromises).then(data => {
          // close redis here
        }).catch(err => {
          console.log(err)
        })
        

        【讨论】:

        • conectToRedisAndSetFunc 是 redis API 未承诺的回调。 redisConnection.set(key, value, function(err, resp) { if (err) { console.log(err) } else { console.log(resp) } });
        • 谢谢!这就是我一直在寻找的。这解决了我的问题。
        • @ShashankSachan 我真的很惊讶你选择这个作为你接受的答案。为什么你不想像我建议的那样使用 API 来做这件事?
        猜你喜欢
        • 2015-10-09
        • 1970-01-01
        • 1970-01-01
        • 2018-09-07
        • 1970-01-01
        • 1970-01-01
        • 2017-06-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多