我在下面编写了代码,试图将视频收集到一个数组中然后返回。代码是错误的,但是我找不到正确的方法。

var redis = require('redis');
var client = redis.createClient();

app.get('/topvideos', function(req, res){
  res.type('application/json');
  var topvideos = [];

  client.hkeys("topvideos", function(err,replies) {
    console.log("Results for video:");
    console.log(replies.length + " videos:");

    replies.forEach(function (reply, i) {

      client.hget("topvideos",i, function (err, reply) {
        console.log(i + ": " + reply );
        topvideos.push(reply);
      });
    });

  }
  var string = JSON.stringify(topvideos)
  res.send(string);
});


有没有我可以遵循的优雅模式?

最佳答案

大概.hkeys方法是异步的。这意味着您必须编写知道所有异步项目何时完成的代码,这样您才可以(并且只有那时)到最终的res.send()并累积结果。

有许多方法可以跟踪所有异步操作何时完成。我最喜欢的是使所有涉及的函数混杂,并使用Promise.all()。但是,由于您尚未在此代码中使用Promise,因此这是一种使用手动计数器的方法。每当您启动异步任务时,请增加计数器。完成异步任务后,递减计数器。当计数器为零时,所有异步操作都将完成:

var redis = require('redis');
var client = redis.createClient();

app.get('/topvideos', function(req, res){
  res.type('application/json');
  var topvideos = [];
  var cntRemaining = 0;

  client.hkeys("topvideos", function(err,replies) {
    console.log("Results for video:");
    console.log(replies.length + " videos:");

    replies.forEach(function (reply, i) {
      ++cntRemaining;

      client.hget("topvideos",i, function (err, reply) {
        console.log(i + ": " + reply );
        topvideos.push(reply);
        --cntRemaining;
        if (cntRemaining === 0) {
           res.send(JSON.stringify(topvideos));
        }
      });
    });

  }
});

09-11 17:39