Node.js 如何在Nodejs循环中将值收集到数组中?
我写了下面的代码,试图收集阵列中的视频,然后返回。代码是错误的,但我想不出正确的方法Node.js 如何在Nodejs循环中将值收集到数组中?,node.js,Node.js,我写了下面的代码,试图收集阵列中的视频,然后返回。代码是错误的,但我想不出正确的方法 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,rep
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()
。但是,由于您还没有在这段代码中使用承诺,这里有一个使用手动计数器的方法。每当启动异步任务时,递增计数器。每当完成异步任务时,减小计数器。当计数器为零时,所有异步操作都将完成:
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));
}
});
});
}
});
您可以使用
hgetall
client.hgetall("topvideos", function(err, videos){
var keys = Object.keys(videos);
res.send(JSON.stringify(keys.map(function(key){return videos[key];})));
});
此外,我建议使用单独的函数包装所有单独的任务,如:
var async = require('async');
function getKeyValueMap(obj) {
return function(key, next) {
return next(null, obj[key]);
}
}
function getValues(obj, next) {
async.map(Object.keys(obj), getKeyValueMap(obj), next);
}
function getVideoList(next) {
client.hgetall("topvideos", function(err, videos){
if (err) return next(null, []);
getValues(videos, next);
});
}
function response(err, data) {
if (err) return res.send(err.message)
return res.send(JSON.stringify(data));
}
getVideoList(response);
@scimonester的可能重复-这是一个与另一个问题类似的问题,但这个答案并没有真正告诉他们如何修复这个更复杂的场景。你在寻找吗?仍然不能单独解决OP的所有问题
res.send()
必须移动。真的吗?为什么?他获取散列键,然后逐字段获取散列字段。这正是hgetall
所做的,使用hgetall()
是异步的,res.send()
必须移动到中。hgetall()
回调或res.send()
将在hgetall()之前被调用
已经完成了它的工作,并且总是没有结果。在第二个代码块的嵌套作用域中为两个不同的目的使用next
是非常令人困惑的。请为其中一个选择不同的变量名。然后,在getVideoList()
中为参数选择不同的名称。两个都是next
让我很难理解你的代码是如何工作的。您可以使其完成
或回调
。我只是给你反馈,你写的代码很难理解和遵循,因为这个问题,它不需要这样。我建议对代码进行改进。