В контексте механизмов Javascript на стороне сервера, что такое неблокирующий ввод-вывод или асинхронный ввод-вывод? Я считаю, что это упоминается как преимущество перед реализациями на стороне сервера Java.
Что такое неблокирующий или асинхронный ввод-вывод в Node.js?
Ответы (2)
Синхронный против асинхронного
Синхронное выполнение обычно относится к последовательному выполнению кода. Асинхронное выполнение относится к выполнению, которое не выполняется в той последовательности, в которой оно отображается в коде. В следующем примере синхронная операция вызывает последовательное срабатывание предупреждений. В асинхронной операции, хотя кажется, что alert(2)
выполняется вторым, это не так.
Синхронный: 1,2,3
alert(1);
alert(2);
alert(3);
Асинхронный: 1,3,2
alert(1);
setTimeout(() => alert(2), 0);
alert(3);
Блокирование против неблокирования
Блокировка относится к операциям, которые блокируют дальнейшее выполнение до завершения этой операции. Неблокирующий относится к коду, который не блокирует выполнение. В данном примере localStorage
- это операция блокировки, поскольку она останавливает выполнение для чтения. С другой стороны, fetch
- это неблокирующая операция, поскольку она не останавливает выполнение alert(3)
.
// Blocking: 1,... 2
alert(1);
var value = localStorage.getItem('foo');
alert(2);
// Non-blocking: 1, 3,... 2
alert(1);
fetch('example.com').then(() => alert(2));
alert(3);
Преимущества
Одним из преимуществ неблокирующих асинхронных операций является то, что вы можете максимально использовать как отдельный процессор, так и память.
Пример синхронной блокировки
Примером синхронных блокирующих операций является то, как некоторые веб-серверы, такие как серверы на Java или PHP, обрабатывают запросы ввода-вывода или сетевые запросы. Если ваш код читает из файла или базы данных, ваш код «блокирует» выполнение всего после него. В этот период ваша машина удерживает память и время обработки для потока, который ничего не делает.
Чтобы обслуживать другие запросы, пока этот поток остановился, зависит от вашего программного обеспечения. Что делает большинство серверного программного обеспечения, так это порождает больше потоков для обслуживания дополнительных запросов. Для этого требуется больше памяти и больше обработки.
Асинхронный, неблокирующий пример
Асинхронные неблокирующие серверы, такие как серверы, созданные в Node, используют только один поток для обслуживания всех запросов. Это означает, что экземпляр Node максимально использует один поток. Создатели разработали его, исходя из того, что узким местом являются операции ввода-вывода и сети.
Когда запросы поступают на сервер, они обслуживаются по очереди. Однако, когда обслуживаемый код должен запросить, например, БД, он отправляет обратный вызов во вторую очередь , и основной поток продолжит работу (он не ждет). Теперь, когда операция DB завершается и возвращается, соответствующий обратный вызов извлекается из второй очереди и помещается в третью очередь, где они ожидают выполнения. Когда движок получает возможность выполнить что-то еще (например, когда стек выполнения опорожняется), он берет обратный вызов из третьей очереди и выполняет его.
Now when the DB operation completes and returns, the corresponding callback pulled out of the second queue
, но как именно работает эта волшебная штука? Есть ли связь между обратным вызовом (в очереди 2) и процессом, отвечающим за запрос к БД?
- person Olivier Boissé; 04.05.2018
var startTime = new Date().getTime();
var getEndTime = () => {
var tempEndTime = new Date().getTime();
var second = (tempEndTime - startTime)/1000
return `took ${second} sec...to finish\n`
}
console.log('1: start App', getEndTime())
setTimeout(()=>{
console.log('2: setTimeout', getEndTime())
}, 1000)
console.log('3: End App', getEndTime())
// console -> Process Order: 1 -> 3 -> 2