У меня есть упрощенная функция, которая выглядит так:
function(query) {
myApi.exec('SomeCommand', function(response) {
return response;
});
}
В основном, я хочу, чтобы он вызывал myApi.exec
и возвращал ответ, который дается в лямбде обратного вызова. Однако приведенный выше код не работает и просто сразу возвращается.
Просто для очень хакерской попытки, я попробовал следующее, которое не сработало, но, по крайней мере, вы поняли, чего я пытаюсь достичь:
function(query) {
var r;
myApi.exec('SomeCommand', function(response) {
r = response;
});
while (!r) {}
return r;
}
По сути, каков хороший способ управления событиями на основе node.js? Я хочу, чтобы моя функция ожидала обратного вызова, а затем возвращала значение, переданное ей.
Ответы:
«Хороший узел.js / управляемый событиями» способ сделать это - не ждать .
Как и почти все остальное при работе с системами, управляемыми событиями, такими как узел, ваша функция должна принимать параметр обратного вызова, который будет вызван после завершения вычислений. Вызывающая сторона не должна ждать возврата значения в обычном смысле, а должна отправить подпрограмму, которая будет обрабатывать полученное значение:
Таким образом, вы не используете это так:
А вот так:
источник
fs
sync*
методы). Таким образом, я думаю, что это все еще актуальный вопрос. Есть хороший способ добиться блокировки в узле, кроме занятого ожидания?sync
делают методы. (2) Используйте волокна, github.com/laverdet/node-fibers , (3) Используйте обещания, например, библиотеку Q, (4) Используйте тонкий слой поверх javascript, который выглядит блокирующим, но компилируется в асинхронный, как maxtaco.github.com/coffee-scriptОдин из способов добиться этого - заключить вызов API в обещание, а затем использовать его
await
для ожидания результата.Вывод:
источник
async/await
мне это часто не нужно, поэтому не могу вспомнить, как справиться с этой ситуацией, я копирую это для моих личных заметок / ссылок.проверьте это: https://github.com/luciotato/waitfor-ES6
ваш код с wait.for: (требуются генераторы, флаг --harmony)
источник
Если вы не хотите использовать обратный вызов, вы можете использовать модуль «Q».
Например:
Для получения дополнительной информации обратитесь к этому: https://github.com/kriskowal/q
источник
Если вы хотите, чтобы было очень просто и легко, без каких-либо необычных библиотек, ожидать выполнения функций обратного вызова в узле, прежде чем выполнять какой-либо другой код, это выглядит так:
источник
Примечание. Этот ответ, вероятно, не следует использовать в рабочем коде. Это взлом, и вы должны знать о последствиях.
Существует модуль uvrun (обновлен для новых версий Nodejs здесь ), где вы можете выполнить один цикл цикла основного события libuv (который является основным циклом Nodejs).
Ваш код будет выглядеть так:
(Вы можете использовать альтернативу
uvrun.runNoWait()
. Это может избежать некоторых проблем с блокировкой, но занимает 100% ЦП.)Обратите внимание, что этот подход делает недействительным всю цель Nodejs, то есть иметь все асинхронное и неблокирующее. Кроме того, это может значительно увеличить глубину стека вызовов, что может привести к переполнению стека. Если вы запустите такую функцию рекурсивно, у вас наверняка возникнут проблемы.
Посмотрите другие ответы о том, как изменить дизайн своего кода, чтобы сделать его «правильным».
Это решение, вероятно, полезно только тогда, когда вы проводите тестирование и ESP. хочу иметь синхронизированный и серийный код.
источник
Начиная с узла 4.8.0 вы можете использовать функцию ES6, называемую генератором. Вы можете следовать этой статье для более глубоких понятий. Но в основном вы можете использовать генераторы и обещания, чтобы выполнить эту работу. Я использую синюю птицу, чтобы обещать и управлять генератором.
Ваш код должен быть в порядке, как в примере ниже.
источник
Предположим, у вас есть функция:
Вы можете использовать обратные вызовы, как это:
источник
Это побеждает цель неблокирования ввода-вывода - вы блокируете его, когда он не нуждается в блокировке
:)
Вы должны вкладывать свои обратные вызовы вместо того, чтобы заставлять node.js ждать, или вызывать другой обратный вызов внутри обратного вызова, где вам нужен результат
r
.Скорее всего, если вам нужно принудительно блокировать, вы думаете о своей архитектуре неправильно.
источник
http.get()
некоторого URL иconsole.log()
его содержимого. Почему я должен перепрыгнуть назад, чтобы сделать это в Node?Использование async и await намного проще.
источник