В контексте механизмов Javascript на стороне сервера, что такое неблокирующий ввод-вывод или асинхронный ввод-вывод? Я считаю, что это упоминается как преимущество перед реализациями на стороне сервера Java.
В контексте механизмов Javascript на стороне сервера, что такое неблокирующий ввод-вывод или асинхронный ввод-вывод? Я считаю, что это упоминается как преимущество перед реализациями на стороне сервера Java.
Ответы:
Синхронное выполнение обычно относится к коду, выполняемому последовательно. Асинхронное выполнение относится к выполнению, которое не выполняется в той последовательности, в которой оно появляется в коде. В следующем примере синхронная операция вызывает срабатывание предупреждений в последовательности. В асинхронной операции, хотя 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 завершается и возвращается, соответствующий обратный вызов извлекается из второй очереди и помещается в очередь в третьей очереди, где они ожидают выполнения. Когда движок получает возможность выполнить что-то еще (например, когда стек выполнения очищается), он выбирает обратный вызов из третьей очереди и выполняет его.
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