Если у меня есть простая функция setTimeout() и установите ее на 10 секунд ...В Node.js, setTimeout() блокирует цикл событий?
Весь сервер мертв в течение этих 10 секунд ??? Это правда? Вот что я слышал.
Если у меня есть простая функция setTimeout() и установите ее на 10 секунд ...В Node.js, setTimeout() блокирует цикл событий?
Весь сервер мертв в течение этих 10 секунд ??? Это правда? Вот что я слышал.
Ответ нет. Какая ваша ссылка Node.js: How would you recreate the 'setTimeout' function without it blocking the event loop? показана не была setTimeout
, блокируя цикл событий, это был цикл while
, который намеренно блокирует цикл событий. Если вы хотите, чтобы ваш сервер был быстрым, вы не хотите блокировать цикл событий. Асинхронный обратный вызов, такой как setTimeout
, будет отлично работать.
Вы пытаетесь заблокировать по какой-то причине (например, тестирование или что-то?)
Кроме того, все вышеприведенное также относится к setInterval. – alessioalex
Это неправда. Когда вы вызываете setTimeout
и возвращаете свой код, сервер не блокируется. Вы можете обрабатывать другие события (возможно, другие обратные вызовы setTimeout
), ожидая, пока ваш конкретный таймер будет стрелять
ссылке, которую Вы, кажется, запутались делает не состояние, которое setTimeout
будет блокировать. Скорее, ОП в этом вопросе пытался создать пользовательскую функцию под названием wait
, которая будет вести себя как setTimeout
. Функция wait
является функцией блокировки - setTimeout
не будет блокироваться.
Другое обнаружение, которое может помочь другим, которые изучают Node.js и интересуются этим вопросом, но обманом скрытого поведения современных браузеров.
Код действительно прост, я просто хочу проверить свое понимание «асинхронного характера» Node.js.
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
console.log("route begin");
var start = new Date();
setTimeout(function() {
res.render('index', { title: start + ' - ' + new Date()});
}, 20000);//force delay of 20 seconds.
console.log("route end");
});
module.exports = router;
Если я начну три окна браузера (Firefox, более точно), откройте URL, определенные по этому маршруту в то же время, и проверьте журнал на консоль Node.js, то ясно, что запрос не обрабатывается одновременно!
Я попробовал тест несколько раз, результаты такие же.
Типичный выход журнала выглядит так:
route begin at: Fri Aug 28 2015 18:35:57 GMT+0800 (CST)
route end at: Fri Aug 28 2015 18:35:57 GMT+0800 (CST)
route begin at: Fri Aug 28 2015 18:36:18 GMT+0800 (CST)
route end at: Fri Aug 28 2015 18:36:18 GMT+0800 (CST)
route begin at: Fri Aug 28 2015 18:36:20 GMT+0800 (CST)
route end at: Fri Aug 28 2015 18:36:20 GMT+0800 (CST)
А также, как ни странно, он не работает в последовательном режиме либо (если Node.js заблокирован SetTimeout, он должен). Интервал между первым и вторым запросами составляет 20 секунд, а второй и третий - всего 2 секунды.
После того, как я почесываю голову довольно долго, я вдруг вспоминаю, что у браузера есть ограничение на соединение на том же хосте!
Итак, я быстро настрою еще один тест, но на этот раз, выпустив несколько команд curl.
Аллилуйя!
route begin at: Fri Aug 28 2015 18:42:51 GMT+0800 (CST)
route end at: Fri Aug 28 2015 18:42:51 GMT+0800 (CST)
route begin at: Fri Aug 28 2015 18:42:53 GMT+0800 (CST)
route end at: Fri Aug 28 2015 18:42:53 GMT+0800 (CST)
route begin at: Fri Aug 28 2015 18:42:55 GMT+0800 (CST)
route end at: Fri Aug 28 2015 18:42:55 GMT+0800 (CST)
Основной процесс, как представляется, monothreaded хозяином и заблокирован setTimeout
или while
.
Тем не менее, есть альтернатива с этим кодом, который работает, как ожидалось, и не блокируют основной процесс или цикл событий:
var express = require('express')
var app = express()
function setTimeoutAsync (callback, time) {
setTimeout(function() {
callback()
}, time)
return 0
}
app.get('/', function (req, res, next) {
console.log("route begin")
var start = +new Date()
setTimeoutAsync(function() {
console.log("route done")
res.json({ delay: ((+new Date()) - start) + 'ms' })
}, 5000)
console.log("route end")
});
app.listen(8000)
В терминале:
route begin // first page
route end
route begin // second page
route end
route begin // third page
route end
route done // first render
route done // second render
route done // third render
Хорошо источники:
https://www.journaldev.com/7462/node-js-architecture-single-threaded-event-loop
Короткий ответ: нет. – voithos
@voithos то что это? http://stackoverflow.com/questions/8949465/node-js-how-would-you-recreate-the-settimeout-function-without-it-blocking-th – TIMEX
Вы прочитали ответы в этой связи? Это не 'setTimeout', который блокировал цикл событий, это была функция' wait() ', которую они реализовали. Это, буквально, просто ждало заданное количество времени (с петлей while, не менее)! Конечно, это будет блокировать. 'setTimeout' не работает. – voithos