Я думаю, это также ожидаемое поведение, поскольку узел js является однопоточным и не может избежать бесконечных циклов.
Node.js больше не является однопоточным , но есть только один основной поток, если вы не создаете рабочие потоки.
Так как же это асинхронное поведение работает под капотом?
Основной поток Node.js работает в цикле: ваш код верхнего уровня запускается и возвращается, затем запускается и возвращается любое действие в очереди (например, обратный вызов таймера), а затем запускается и возвращается следующее действие в очереди и т. Д. Вот как работает setTimeout
: когда пора срабатывать таймеру, цикл обработки событий видит это и ставит в очередь вызов обратного вызова таймера. Также обратите внимание, что хотя Node.js по умолчанию имеет только один основной поток JavaScript, это не означает, что сам Node является однопоточным. В частности, он может выполнять обработку ввода-вывода в другом внутреннем потоке.
Можно ли создать мою собственную функцию, которая будет работать асинхронно, как setTimeout?
Только используя что-то, что уже обеспечивает асинхронное поведение, и упаковывая его. Это будет включать:
setTimeout
setImmediate
process.nextTick
- Обратный вызов
then
или catch
обещания
На первый взгляд вы можете подумать, что async
функции делают это, но на самом деле это не так: код в async
функции запускает синхронно вплоть до первого ожидания обещания. разрешение (или до тех пор, пока оно не вернется). Таким образом, асинхронность в действительности такая же, как и в последнем пуле выше: обратный вызов then
или catch
.
То, что вы не можете сделать (без рабочего потока), занято-ждать, как это делает ваш pollingWait
, потому что больше ничего не может произойти с потоком, в котором выполняется занятое ожидание.