setTimeout()
является «неблокирующим». Это означает, что он устанавливает таймер, немедленно возвращается из setTimeout()
и затем продолжает выполнять остальную часть кода.
Итак, в вашем случае /route2
создает два обещания, устанавливает два таймера, а затем ждет, пока Promise.all()
достигнет конечного значения sh. В тот момент, когда он достигает await
, ваш обработчик маршрута async
возвращает обещание и возвращает управление обратно событию l oop.
Итак, как только приходит запрос /route1
, он готов к обработке. /route2
не активен до тех пор, пока не будут выполнены оба таймера.
Затем, когда более длинный таймер готов к срабатыванию, в следующий раз, когда интерпретатор JS вернется к событию l oop, чтобы проверить что-либо в противном случае он увидит, что таймер обработает обратный вызов таймера, и этот обратный вызов таймера разрешит обещание p1
, а затем вызовет разрешение Promise.all()
.
Если я нажму / route2 Я получаю ответ через 15 секунд, но в течение этого времени / route1 дает ответ немедленно. Сервер не должен ждать 15 секунд, а затем дать ответ /route1.
Как объяснено, setTimeout()
неблокирует, так что пока обработчик /route2
ожидает срабатывания двух таймеров, nodejs может обрабатывать другие события (например, входящее /route1
событие).
Я понял, что / route2 является консолью P1, тогда как setTimeout () помещается в внешний поток, затем консоль P2, затем, как setTimeout (), поместите его во внешний поток. Теперь дождитесь, пока setTimeouts () достигнет значения fini sh.
Таймеры не запускаются во внешних потоках. Они являются несколько уникальным дизайном в nodejs событии l oop. Таймеры хранятся в отсортированном связанном списке в порядке их наступления. Каждый раз, когда интерпретатор JS возвращается к событию l oop и попадает в секцию таймера события l oop, он просто проверяет самый передний таймер в связанном списке, чтобы узнать, наступило ли его время. Если так, это вызывает это событие. Если нет, он просто идет и ищет другие типы событий.
В конце концов, если событие l oop не имеет ничего общего и переходит в режим сна, оно будет спать в течение соответствующего времени, чтобы проснуться вовремя для следующего таймера, запланированного для запуска (если больше ничего его не разбудит до этого).
(В это время событие l oop должно быть занято, так как оно ожидает полного заполнения p1 и p2, поэтому он не должен принимать новый запрос клиента). Но это так. Почему?
Это ваше главное неверное предположение. В это время событие l oop может свободно обрабатывать другие события. Два таймера установлены, и событие l oop будет запускать их обратные вызовы, когда истечет их время, но до тех пор событие l oop будет обрабатывать любые другие входящие события, такие как /route1
запрос.