Все функции Node.js обратного вызова асинхронны?

Я работаю над обучением Node.js, и все, что я слышу в каждом учебнике, это "Node является асинхронным и не-блочным!"

Я слышал, что в обычном браузере JavaScript некоторые вещи, такие как вызовы AJAX, могут быть сделаны асинхронными или неблокирующими (с использованием обратных вызовов)... Это относится и к Node.js, либо все они Node.js функции обратного вызова, сделанные асинхронными/неблокирующими?

Ответ 1

- все Node.js функции обратного вызова, сделанные асинхронными/неблокирующими?

Нет. Только I/O обычно является асинхронным, но многие другие обратные вызовы являются синхронными. Всегда проверяйте документы.

Примеры асинхронных функций:

  • Async Доступ к файловой системе (хотя у них есть синхронизирующие копии без обратных вызовов)
  • Таймеры (setTimeout)
  • process.nextTick, setImmediate
  • большинство подключений к базе данных
  • сетевые подключения
  • Promises

Примеры обратных вызовов синхронизации:

См. также Являются ли все обратные вызовы javascript асинхронными? Если нет, как узнать, что такое? (включая некоторые другие примеры).

Ответ 2

Когда вы передаете обратный вызов функции, вы ожидаете, что функция вызовет вашу функцию обратного вызова в другое время. Однако он не является автоматически асинхронным.

Предположим, что у меня есть этот код:

function callSomething(callback) {
  callback();
}

function theCallback() {
  // Do something time consuming here
}

callSomething(theCallback);

В этом случае мы передаем обратный вызов, но обратный вызов вызывается немедленно в существующем стеке вызовов. Это считается плохой практикой и сильно обескуражен в Node.js. Если вы хотите сразу вызвать обратный вызов, используйте process.nextTick():

function callSomething(callback) {
  process.nextTick(callback);
}

Поэтому прямой ответ на ваш вопрос в основном да. Когда вы указываете обратный вызов для функций в Node.js, по соглашению они будут вызываться в другой стоп-код в более поздний момент времени. Но если вы используете какой-то плохой код от кого-то, кто не знал, как следовать этому соглашению, нет никакой гарантии.

Ответ 3

Нет, они не являются автоматически асинхронными. Рассмотрим этот код:

function foo(array, filter, callback) {
    var result = []
    for (var i = 0; i < array.length; i++) {
        if (filter(array[i])) result.push(array[i]);
    }

    callback(result);
}

А теперь представьте себе такую ​​программу:

foo([ 1, 2, 3, 4 ], function() { while(true); }, console.log);
console.log('Blocking?');

Если foo будет асинхронным, то Blocking? будет немедленно отображаться, но это не так!


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