#javascript #node.js #redis
#javascript #node.js #redis
Вопрос:
Я не очень разбираюсь в Nodejs и его асинхронных способах. Я пытаюсь запросить разные базы данных redis.
У меня есть простая функция для получения ключа из базы данных redis:
function get_key(client, key, db, callback) {
if (key) {
client.select(db, function(e, s) {
if (e) {
console.log('client.select err: ' e);
} else if (s) {
client.get(key, function(e, s) {
callback(e, s);
return s;
});
}
});
}
return
}
И я использую его для запроса нескольких баз данных следующим образом:
get_key(client, key1, 0, function(e, s) {
if (s) {
// do stuff with s;
} else {
debug('e: ' e);
}
});
get_key(client, key2, 1, function(e, s) {
if (s) {
// do stuff with s;
} else {
debug('e: ' e);
}
});
но он не работает. Но если я создаю разные клиенты для каждого запроса, это работает. У меня есть запросы в более чем дюжине баз данных, и я бы не предпочел создавать нового клиента каждый раз, когда я выполняю запрос.
Есть ли лучший способ сделать это? способ «узла», с которым я не знаком? Спасибо.
Ответ №1:
Асинхронные функции принимают функцию обратного вызова в качестве параметра. Функция возвращает значение, близкое к немедленному, и обратный вызов вызывается после завершения работы, а не блокирует вызывающего абонента. Таким образом, ваш первый вызов возвращается до завершения его вызовов в redis, и второй вызов выполняется немедленно, что, вероятно, приводит к сбою первого вызова, потому что они используют один и тот же клиент.
Если вам нужно выполнить только два вызова, простой ответ — поместить второй вызов в обратный вызов первого вызова. Если вам нужно выполнить много последовательных асинхронных вызовов, рассмотрите возможность использования promises или некоторых доступных библиотек, таких как async.
Комментарии:
1. Итак, в функции get_key() возврат в конце выполняется до того, как функция обратного вызова даже вызывается? Кроме того, нет ли достойного способа сделать это в nodejs без использования каких-либо внешних модулей? Да, мне нужно сделать много вызовов, и я бы предпочел не использовать другие библиотеки / модули. Неужели в nodejs нет способа сделать это чисто?
2. Это выглядит примерно так
if (key) start select request and return, continue select when response comes back, then call the callback with the results
. Идея состоит в том, чтобы не блокировать один поток узла, ожидающий завершения операций ввода-вывода. Вы можете поместить столько вызовов внутри обратных вызовов, сколько захотите, не используя библиотеку, но ваш код может в конечном итоге выглядеть как огромная пирамида скобок. Библиотеки улучшают читаемость и обеспечивают структуру, и, fwiw, они не зависят от nodejs, например, promises также используются в javascript браузера.3. Да, но я едва понимаю nodejs достаточно, я бы не предпочел использовать другую внешнюю среду только для улучшения удобочитаемости. Я думаю, что если это стандартный способ делать что-то в nodejs, возможно, они не должны включать его в стандартную библиотеку. В любом случае, спасибо. Я пойду дальше и пока использую node-async.