Я проходил обучение node JS на канале newboston (ссылка https://thewikihow.com/video_KsjrN-T3ZCs). и Пример того, как Node обеспечивает лучшую производительность, показан ниже.
function placeAnOrder(orderNumber) {
console.info("Order placed", orderNumber);
cookAndDeliver(function () {
console.info("Delivered order", orderNumber);
});
};
function cookAndDeliver(callback){
setTimeout(callback, 5000);
};
placeAnOrder(1);
placeAnOrder(11);
placeAnOrder(111);
placeAnOrder(1111);
placeAnOrder(11111);Если вы запустите образец, вы заметите, что сначала все заказы размещаются одновременно, что нормально, а затем все заказы также доставляются один раз, что не является нормальным, поскольку уже существует ограничение тайм-аута в 5 секунд, применяемое для каждого вызова.
Объяснение, данное видео, заключалось в том, что обратный вызов не является препятствием, и код будет выполняться без прерывания, с чем я согласен, но я не понимаю, почему узел не соблюдает значение тайм-аута?
Я предполагаю, что, поскольку он работает в асинхронном режиме, это означает, что отдельный поток будет обрабатывать каждый вызов, верно ли мое предположение?
@Keith Поскольку я пришел из фона java, я понимаю, что либо выполнение будет синхронным, тогда каждый вызов функции будет происходить после другого, либо выполнение будет асинхронным, поэтому каждый вызов будет выполняться в отдельном потоке, а затем все могут закончите аналогично тому, что было объяснено выше. не могли бы вы подробнее рассказать, как это можно сделать без асихоничности?
@Baao Спасибо за это, это действительно помогло понять, как работает цепочка, однако мой вопрос касается характера выполнения (синхронизация против асинхронного), а теперь о том, где именно узел решает начать обработку запроса в другом потоке.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Это соблюдает тайм-аут. Тайм-аут предназначен для обратного вызова, а не для выполнения функции. Итак, произошло то, что все ваши вызовы функций выполнялись асинхронно, и все они ждали пять секунд, и все они вернулись. Таким образом, все они прошли пять секунд между началом и завершением. Узлу не нужно ждать завершения первой функции до завершения второй.
В основном для нетривиального примера, то есть ожидания вызова db. вам не нужно ждать завершения одного вызова db перед отправкой второго вызова db. И если БД является многопоточным, вы можете получить результаты практически одновременно.
Это мое понимание, поправьте меня, если я ошибаюсь, это означает, что либо каждый вызов функции cookAndDeliver выполняется в отдельном потоке, либо каждый placeAnOrder выполняется в отдельном потоке
Узел является однопоточным, он просто использует асинхронный цикл обработки событий. Он использует концепцию тиков, чтобы отслеживать все. Таким образом, с таймаутом он в основном проверяет на каждой итерации цикла событий, выполняется ли тайм-аут для каждого вызова функции.
Вот последовательность событий:
placeAnOrder()cookAndDeliver()setTimeout()setTimeout() планирует событие таймера на 5 секунд с этого момента и немедленно возвращается.placeAnOrder()cookAndDeliver()setTimeout()setTimeout() планирует событие таймера на 5 секунд с этого момента и немедленно возвращается.placeAnOrder()cookAndDeliver()setTimeout()setTimeout() планирует событие таймера на 5 секунд с этого момента и немедленно возвращается.Здесь нет веток Javascript. Javascript в node.js однопоточный. Все проходит через центральную очередь событий. В Javascript могут быть внутренние элементы, которые используют потоки для выполнения асинхронных операций (например, ввод-вывод асинхронного файла использует потоки, внутренние по отношению к его реализации, но не для запуска Javascript). Когда эти потоки завершены, они помещают событие в очередь событий, и когда единственный поток Javascript node.js завершает выполнение того, что он делал, он затем захватывает следующее событие из очереди событий и выполняет связанный с ним обратный вызов.
My guess is that since it operates in an asynchronous mode then it means that a separate thread is going to handle each call, is my assumption correct?
Нет, это не так. setTimeout() планирует событие таймера на некоторое время в будущем. Нет потока Javascript, связанного с событием таймера. Может быть или не быть одного системного потока, который управляет всеми событиями таймера (это зависит от реализации и на самом деле не имеет значения - также может быть, что всякий раз, когда Javascript возвращается в цикл событий, он просто проверяет, не пришло ли время запустить следующее событие таймера). Когда наступает время срабатывания таймера, событие вставляется в очередь событий Javascript. Затем интерпретатор JS выбирает это событие из цикла событий в следующий раз, когда он завершит обработку и ищет следующее событие для обработки.
An example was given on how Node provides better performance is shown below
Я думаю, что они пытались показать, что из-за асинхронной управляемой событиями конструкции node.js НЕ существует нескольких потоков для асинхронных событий, таких как таймеры. Это позволяет ему лучше масштабироваться при одновременном выполнении множества асинхронных операций, поскольку его модель более эффективна, чем модель, в которой для каждого таймера есть системный поток.
Should you run the sample, you will notice that first all order placed at once, which is normal, and then all of the orders are also delivered once, which is not normal since there is already a timeout constraint of 5 seconds applied per call.
По сути, код запускает 5 вызовов setTimeout() подряд, и все они устанавливают таймер на срабатывание через 5 секунд. setTimeout() не блокирует. Это означает, что он планирует таймер на 5 секунд с этого момента, а затем НЕМЕДЛЕННО переходит к следующей строке кода, которая также планирует таймер на 5 секунд с этого момента. Таким образом, вы получите 5 таймеров, все запланированные примерно на 5 секунд с этого момента (возможно, варьируется всего несколько миллисекунд времени выполнения от одного вызова setTimeout() до следующего. Конечным результатом является то, что все 5 таймеров сработают примерно через 5 секунд, и они будут срабатывать в том порядке, в котором они были запланированы.
The explanation given by the video was that the call back is none-obstructive and the code will execute unintrrupted, which I concur with, what I don't get is why the node did not honor the timeout value?
Поскольку setTimeout() не блокирует (как и все асинхронные операции в node.js). Он планирует таймер на некоторое время в будущем, а затем немедленно возвращается (это неблокирующая часть). Он не ждет 5 секунд, чтобы вернуться. Он немедленно возвращается и выполняет любой следующий код. Затем через 5 секунд (когда интерпретатору JS больше нечего делать) будет вызван обратный вызов таймера.
is my assumption correctНет, все, что вы сделали, это установили таймаут на 5 секунд для всего, так что через 5 секунд все произойдет. Вы не создали цепочку setTimeout's ..