Всегда ли в блокирующем коде используются операторы возврата, а в неблокирующем коде всегда используется обратный вызов? - PullRequest
1 голос
/ 26 октября 2011

В обучающих программах для начинающих, неблокирующая природа узла обычно демонстрируется, показывая пример блокирования (используя оператор return) и пример неблокирующего узла (используя обратные вызовы).Для примера, смотрите здесь .

Должен ли я воспринимать это как «запах», что использование return создает блокирующий код в моем приложении Node, и найти способ повторить его с помощью обратных вызовов

Ответы [ 3 ]

4 голосов
/ 26 октября 2011

TL; DR: если код может занять "долгое" время, может быть чище / эффективнее справиться с обратным вызовом.

Этоне о возврате / не возвращении, а о том, что на самом деле делает код.

Пример функции не блокирует , потому что есть возврат, он блокируется, потому что db.query принимает произвольную суммувремени.Если вы хотите заняться другими делами в течение этого времени, сразу же вернитесь и выполните обработку результата в обратном вызове.

Независимо от того, должны ли вы , зависеть от того, что на самом деле происходит, что ещемогут зависеть или зависеть от данных, переданных обратному вызову (или возвращенным) и т. д.

1 голос
/ 26 октября 2011

Блокирующие вызовы обычно возвращают что-то, потому что возврат происходит после «действия», вызванного вызовом, поэтому он может возвращать информацию об успехе или неудаче действия и любые данные, полученные в результате действия.Это относится также к вызовам, которые не блокируют сами по себе, но не выполняют ввод-вывод, поэтому обратный вызов не требуется.

Неблокирующие вызовы, например, вызов функции, которая читает файл, не склонны использовать возвращаемое значение, потому что они обычно возвращаются до того, как они что-либо значат.Вместо этого они вызывают обратный вызов и отправляют ему все полученные данные или, возможно, сообщение об ошибке.

0 голосов
/ 26 октября 2011

Основная мотивация использования неблокирующего вызова заключается в том, что вы ожидаете возврата какого-либо внешнего процесса или устройства, поэтому вы освобождаете контроль над потоком, чтобы другие операции могли выполняться «пока вы ждете».

Поскольку неблокирующий / асинхронный код с использованием обратных вызовов труднее писать, читать и обслуживать, следует избегать неблокирующего кода, за исключением случаев, когда это будет иметь значение для производительности и масштабируемости вашего приложения или там, где это требуется с помощью API, который вы используете.

Рассмотрим этот относительно глупый пример:

  function add(a,b,cb) { cb(a+b); }
  console.log('2+2 is', add(2,2)); // -> 4

  function add(a,b) { return a+b; }
  add(2,2,function(sum) { console.log('2+2 is', sum); }); // -> 4

Первый из них немного проще для глаз.

Многие нодовые API имеют асинхронную версию, но не имеют синхронной версии. При использовании этих API будет очевидно, что вам нужно сделать свой код асинхронным.

В тех случаях, когда у вас есть выбор (например, при чтении файла), спросите себя: «Будет ли блокирующий вызов заставлять конечного пользователя ждать неоправданное количество времени?». Во время запуска приложения ответ обычно «нет», потому что этот код запускается только один раз, и у конечных пользователей не было возможности прикоснуться к серверу. Однако, если вы отвечаете на веб-запрос, то заставляя всех пользователей ждать исходящего вызова API или чтения с диска, это замедлит работу сайта для всех пользователей, тогда как неблокирующий вызов позволяет узлу продолжать обрабатывать новые запросы до тех пор, пока вы не получите данные. Запрошенный возвращается.

...