2013-08-26 4 views
0

Когда я определяю свои маршруты в node.js, я пытаюсь вызвать некоторое промежуточное программное обеспечение для загрузки пользователей в зависимости от запроса. Однако асинхронный характер вытаскивания пользователей из базы данных, по-видимому, делает невозможным.Асинхронные обратные вызовы невозможны nesting

Middleware, который использует другую функцию для подключения к базе данных

function loadUsers (req, res, next) { 
    userings.openPlayers(function(ps) { 
    req.user = ps[req.params.id - 1]; 
    }); 
    console.log(req.user); 
} 

маршрут, который использует промежуточное программное

app.get('/player/game/:id', loadUsers, function(res, req) { 
    console.log(req.user); 
}); 

Функция, которая подключается к БД и возвращает пользователям обратного вызова

function openPlayers(callback) { 
    db.hgetall("players", function(err, objs) { 
    var players = []; 
    // Objects of Response 
    for (var k in objs) { 
     // Items are the individual key-value object 
     var newPlayer = {}; 
     var items = JSON.parse(objs[k]); 
     for (var x in items) { 
     // x is the key for each object 
     newPlayer[x] = items[x]; 
     } 
     players.push(newPlayer); 
    } 
    callback(players); 
    }); 
} 
module.exports.openPlayers = openPlayers; 

Функция подключения к базе данных отлично работает! Моя конкретная проблема заключается в том, как использовать обратный вызов, чтобы вернуть пользователей функции loadUsers, чтобы мой маршрут мог использовать ее в качестве промежуточного программного обеспечения. Спасибо!

+0

Вы хотите вызвать ':

Было бы, вероятно, будет лучше держать Object, используя свои ключи как :id и просто преобразование значения из JSON в Object себя S next() 'из обратного вызова. – Bergi

+0

'req.user' по-прежнему возвращается как' undefined' с маршрута. –

+0

Я проверил подтвержденное, что оно возвращает ожидаемое значение. Я немного озадачен этим вопросом после нескольких часов отладки. –

ответ

2

Не забудьте позвонить next в вашем промежуточного

app.use(function (req, res, next) { 
    userings.openPlayers(function(ps) { 
    req.user = ps[req.params.id - 1]; 
    next(); 
    }); 

    // this is pointless here 
    // console.log(req.user); 
}); 

req.user устанавливается только в функции обратного вызова для функции openPlayers.

+0

. Благодарим вас за ответ, но это не так. Исправить проблему, как вы сказали. Я пытаюсь получить 'req.user', чтобы вернуться к промежуточному программному обеспечению без бесконечной последовательности обратных вызовов ... –

+0

@derek_duncan: Что вы подразумеваете под« бесконечной цепочкой обратных вызовов »? – Bergi

+0

В настоящее время я пытаюсь не добавлять еще один обратный вызов, чтобы исправить это. Любые идеи о том, почему 'next()' не возвращает значение? –

1

Другая проблема может заключаться в преобразовании Objectthat hsetall() supplies в Array.

Порядок, в котором for..in перебирает ключи в Object не гарантируются (кроме того, что не повторится), так что порядок игроков/пользователи могут появиться изменить в ps от одного обращения к другим.

for (var k in objs) 
    objs[k] = JSON.parse(objs[k]); 

callback(objs); 
req.user = ps[req.params.id]; 
+0

+1 для гораздо лучшего метода, но проблема все еще не решена.Маршрут не может возвращать объект пользователя из обратного вызова даже с помощью 'next()' –

+0

@derek_duncan. Ожидается, что результат появится? На основе фрагмента пользователь должен войти в STDOUT. Но, если вы ожидаете, что он появится в HTTP-клиенте (браузере), вам нужно будет использовать ['res.write()' и 'res.end()'] (http://nodejs.org/ апи/http.html # http_response_write_chunk_encoding). Вы также можете использовать Express '['res.send()' или 'res.json()'] (http://expressjs.com/api.html#res.send), которые являются сокращенными для других 2 методов. –

+0

Это работает, если я вызываю его в функции 'loadUsers'. Есть ли способ вызвать его из маршрута 'app.get', вместо того, что я изначально тестировал с помощью' console.log'? –

Смежные вопросы