Javascript 计算Node.js+;Redis+;Express.js和可爱的异步回调
首先,请原谅我,这对我来说是一个非常未经授权的领域 获得以下信息:Javascript 计算Node.js+;Redis+;Express.js和可爱的异步回调,javascript,node.js,asynchronous,express,redis,Javascript,Node.js,Asynchronous,Express,Redis,首先,请原谅我,这对我来说是一个非常未经授权的领域 获得以下信息: app.get('/user/:user_id/followings', function(req, res) { var response = {} , userId = req.params.user_id , ids = req.param('id').split(',') , prefix = 'user' , suffix = 'follower_ids';
app.get('/user/:user_id/followings', function(req, res) {
var response = {}
, userId = req.params.user_id
, ids = req.param('id').split(',')
, prefix = 'user'
, suffix = 'follower_ids';
for (var i=0; i<ids.length; i++) {
var id = ids[i]
, key = prefix+':'+ids[i];
console.log('1: ' + key);
checkMembership(userId, id, key, suffix, function(error, reply){
response[key] = reply;
console.log('2: ' + key + ': ' + reply);
});
}
res.json(response);
});
function checkMembership(userId, id, key, suffix, callback) {
var lookup = key+':'+suffix;
client.sismember(lookup, userId, callback);
}
在浏览器中:
{}
我知道这是因为事情是异步发生的。。。我只是不知道如何修复它
checkMembership功能中记录的密钥错误。控制台应输出第二次回调,如下所示:
2: user:1: 0
2: user:2: 1
2: user:3: 1
2: user:4: 1
2: user:1000: 0
救命啊 您是对的,这是因为checkMembership是异步的。因此,当checkMembership仍在等待答案时,for循环已完成 让我们从简化示例开始:
for (i = 0; i < 3; i += 1) {
console.log('inside: ', i);
process.nextTick(function () {
console.log('outside: ', i);
});
};
console.log('end');
因此,第一个问题是当计数器已经在2时执行回调。您可以通过创建闭包来修复此问题
for (i = 0; i < 3; i += 1) {
console.log('inside: ', i);
(function () {
var j = i;
process.nextTick(function () {
console.log('outside: ', j);
});
})();
};
console.log('end');
这将解决response[key]=reply的问题代码>
本例的第二个问题是,在异步函数完成之前会记录end。在您的代码中,这意味着在设置键+回复之前,将调用res.json
所以,我们需要找出所有回调何时完成,然后才能记录结束。因为你知道你的列表有多大,你也知道有多少回调。这意味着我们可以在每次回调完成时进行计数。如果计数大小相等,则知道调用了所有回调
在代码中,它如下所示:
var size = 3;
var counter = 0;
var globalCallback = function () {
counter += 1;
if (counter === size) {
console.log('end');
}
}
for (i = 0; i < size; i += 1) {
console.log('inside: ', i);
(function () {
var j = i;
process.nextTick(function () {
console.log('outside: ', j);
globalCallback();
});
})();
};
与每次有异步函数列表时都编写这样的计数器不同,我更喜欢使用控制流库。类似async.js的东西非常流行
帮助我的是对我的代码有一个更实用的视图。您必须将其视为一个值列表,并为每个值应用一个函数。这也是async.js看起来有点像Underline.js的原因。您是对的,这是因为checkMembership是异步的。因此,当checkMembership仍在等待答案时,for循环已完成
让我们从简化示例开始:
for (i = 0; i < 3; i += 1) {
console.log('inside: ', i);
process.nextTick(function () {
console.log('outside: ', i);
});
};
console.log('end');
因此,第一个问题是当计数器已经在2时执行回调。您可以通过创建闭包来修复此问题
for (i = 0; i < 3; i += 1) {
console.log('inside: ', i);
(function () {
var j = i;
process.nextTick(function () {
console.log('outside: ', j);
});
})();
};
console.log('end');
这将解决response[key]=reply的问题代码>
本例的第二个问题是,在异步函数完成之前会记录end。在您的代码中,这意味着在设置键+回复之前,将调用res.json
所以,我们需要找出所有回调何时完成,然后才能记录结束。因为你知道你的列表有多大,你也知道有多少回调。这意味着我们可以在每次回调完成时进行计数。如果计数大小相等,则知道调用了所有回调
在代码中,它如下所示:
var size = 3;
var counter = 0;
var globalCallback = function () {
counter += 1;
if (counter === size) {
console.log('end');
}
}
for (i = 0; i < size; i += 1) {
console.log('inside: ', i);
(function () {
var j = i;
process.nextTick(function () {
console.log('outside: ', j);
globalCallback();
});
})();
};
与每次有异步函数列表时都编写这样的计数器不同,我更喜欢使用控制流库。类似async.js的东西非常流行
帮助我的是对我的代码有一个更实用的视图。您必须将其视为一个值列表,并为每个值应用一个函数。这也是async.js看起来有点像Underline.js的原因。这肯定澄清了我从各种来源读到的内容。谢谢!所以我想我需要基本上用回调链接回调。如果有更好的条件,请原谅。我签出了async.js。。。然而,我想我还是先把异步作为一个概念,然后再深入其中。实际上,我不确定异步在幕后使用哪种技术。源代码非常好,因此您可以查看它以了解更多信息。另一个解决方案可能是承诺。它们有点争议,我不能对此发表评论,因为我从未使用过它们。这肯定澄清了我从各种来源阅读的内容。谢谢!所以我想我需要基本上用回调链接回调。如果有更好的条件,请原谅。我签出了async.js。。。然而,我想我还是先把异步作为一个概念,然后再深入其中。实际上,我不确定异步在幕后使用哪种技术。源代码非常好,因此您可以查看它以了解更多信息。另一个解决方案可能是承诺。它们有点争议,我不能对此发表评论,因为我从未使用过它们。
inside: 0
inside: 1
inside: 2
outside: 0
outside: 1
outside: 2
end