Несколько клиентских запросов в NodeJs - PullRequest
1 голос
/ 02 апреля 2020

Если я нажимаю / route2, я получаю ответ через 15 секунд, но в течение этого времени / route1 дает ответ немедленно. Не должен ли сервер подождать 15 секунд, а затем дать ответ на /route1.

Я прочитал https://medium.com/@cinish / nodejs -multiple-client-запросы-694d6353218b , но идея не могла .

То, что я понял, это то, что / route2 является хитом консоли P1, затем, когда есть setTimeout (), поместите его во внешний поток, затем консоль P2, затем, как setTimeout (), поместите его во внешний поток. Теперь дождитесь setTimeouts () в fini sh.

(в это время событие l oop должно быть занято, так как оно ожидает выполнения p1 и p2, поэтому оно не должно принимать новый клиентский запрос). Но это так. Почему?

app.get("/route1", (req, res) => {
    res.send("Route1");
});


app.get("/route2", async (req, res) => {

    const p1 = new Promise((resolve, reject) => {
        console.log("P1");
        setTimeout(() => {
            console.log(5);
            resolve();
        }, 15000);
    })
    const p2 = new Promise((resolve, reject) => {
        console.log("P2")
        setTimeout(() => {
            console.log(1);
            resolve();
        }, 1000);
    });

    const ans = await Promise.all([p1, p2]);
    res.send("Route2");
})

1 Ответ

1 голос
/ 02 апреля 2020

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 запрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...