Все функции 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
.