За цикл получить предметы из Redis Delay
Я использую Node.js w/ node_redis и перебираю объект и ищу данные в Redis, а затем возвращаю результаты.
У меня это настроено так:
for (var key in items) {
if (items.hasOwnProperty(key)) {
app.client.llen(items[key].id+'_click', function(err, total) {
items[key].total = total;
});
}
}
callback(items);
Проблема в том, что он проходит до завершения вызова redis. Таким образом, вызывается обратный вызов, прежде чем он на самом деле обновляет общее значение. Также кажется, что некоторые пункты пропускаются из-за задержки.
Есть ли лучший способ справиться с этим?
Спасибо!
РЕДАКТИРОВАТЬ:
Итак, я обновил это так:
getTotal(function () {
callback(items);
});
getTotal = function (callback) {
var count = 1;
for (var key in items) {
if (items.hasOwnProperty(key)) {
app.client.llen(items[key].id + '_click', function (err, total) {
items[key].total = total;
if (items.length == count) {
callback();
}
count++;
});
};
}
Похоже, что это сработает, он вызывает обратный вызов в соответствующее время, однако кажется, что только последний ключ обновляется полностью.
1 ответ
Ваш первый пример не может работать, потому что цикл является синхронным, в то время как вызовы клиента Redis являются асинхронными. Ваш второй пример не работает намного лучше из-за управления закрытием Javascript. Вам нужна правильная область действия в самом цикле, чтобы замыкание обрабатывалось правильно, и все полные поля обновлялись соответственно.
Использование forEach кажется здесь проще:
getTotal = function (callback) {
var count = 0;
Object.keys( items ).forEach( function(key) {
++count;
app.client.llen(items[key].id + '_click', function (err, total) {
items[key].total = total;
if ( --count == 0 ) {
callback( items );
}
})
})
}
getTotal( function(items) {
console.log( items );
})