gpt4 book ai didi

javascript - 搞清楚 Node.js + Redis + Express.js 和可爱的异步回调

转载 作者:可可西里 更新时间:2023-11-01 11:05:16 26 4
gpt4 key购买 nike

首先,请原谅我,这对我来说是一个非常未知的领域......

得到以下内容:

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);
}

对于以下路径:/user/1/followings?id=1,2,3,4,1000

我在控制台中得到了这个:

1: user:1
1: user:2
1: user:3
1: user:4
1: user:1000
2: user:1000: 0
2: user:1000: 1
2: user:1000: 1
2: user:1000: 1
2: user:1000: 0

在浏览器中: {}

我知道它正在发生,因为事情是异步发生的......我只是不确定如何解决它。

checkMembership 函数中记录的键是错误的。控制台应为第二次回调输出如下:

2: user:1: 0
2: user:2: 1
2: user:3: 1
2: user:4: 1
2: user:1000: 0

帮助!

最佳答案

你是对的,因为 checkMembership 是异步的。因此,您的 for 循环已完成,而 checkMembership 仍在等待答案。

让我们从简化示例开始:

for (i = 0; i < 3; i += 1) {     

console.log('inside: ', i);

process.nextTick(function () {
console.log('outside: ', i);
});

};

console.log('end');

输出:

inside:  0
inside: 1
inside: 2
end
outside: 2
outside: 2
outside: 2

所以第一个问题是回调是在计数器已经是 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');

输出:

inside:  0 
inside: 1
inside: 2
end
outside: 0
outside: 1
outside: 2

这将通过 response[key] = reply; 解决您的问题。

这个例子的第二个问题是 end 在异步函数完成之前被记录下来。在您的代码中,这意味着 res.json 将在 checkMembership 完成设置键 + 回复之前调用。

所以我们需要找出所有回调何时完成才能记录结束。因为您知道您的列表有多大,所以您也知道有多少回调。这意味着我们可以计算每次回调完成的时间。如果计数相等,您就知道所有回调都已调用。

在代码中它看起来像这样:

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();
});
})();

};

我们的最终输出:

inside:  0
inside: 1
inside: 2
outside: 0
outside: 1
outside: 2
end

我更喜欢使用控制流库,而不是每次你有一个异步函数列表时都像这样编写一个计数器。像 async.js 这样的东西非常流行。

帮助我的是对我的代码有一个更实用的 View 。您必须将其视为值列表,并且您要为每个值应用一个函数。这也是 async.js 看起来有点像 underscore.js 的原因。

关于javascript - 搞清楚 Node.js + Redis + Express.js 和可爱的异步回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14057807/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com