Что такое неблокирующий или асинхронный ввод-вывод в узле.Джей?


в контексте движков Javascript на стороне сервера, что такое неблокирующий ввод-вывод или асинхронный ввод-вывод? Я вижу, что это упоминается как преимущество перед реализациями на стороне сервера Java.

2 107

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, обрабатывают IO или сетевые запросы. Если ваш код читает из файла или базы данных, ваш код "блокирует" все после его выполнения. В этот период ваша машина удерживает память и время обработки для потока это ничего не делает.

для того, чтобы удовлетворить другие запросы в то время как этот поток застопорился зависит от вашего программного обеспечения. То, что делает большинство серверных программ, порождает больше потоков для удовлетворения дополнительных запросов. Это требует больше памяти и больше обработки.

асинхронный и неблокирующий пример

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

когда запросы поступают на сервер, они обслуживаются по одному за раз. Однако, когда обслуживаемый код должен запрашивать БД, например, он отправляет обратный вызов во вторую очередь и основной поток будет продолжаться работает (не ждать). Теперь, когда операция 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

Code example