Исправьте меня, если я ошибаюсь, но в javascript очередь обратного вызова - fifo, сначала укладывает поток и выходите первым?
Не совсем. Асинхронные обратные вызовы обрабатываются FIFO в порядке, в котором они завершают свои операции, а не в порядке их запуска. Таким образом, время, которое требуется выполнить операции, очень важно при определении того, когда обратный вызов будет назначен. Короткие операции могут завершаться до завершения операций, даже если они были запущены позже.
Требуется время, чтобы открыть файл и начать его читать, а setTimeout()
не требует времени, чтобы это произошло первым. Когда у вас есть независимые асинхронные операции, вы почти никогда не можете «знать», в каком порядке они будут происходить, потому что это зависит от внутреннего времени различных функций.
Операция readStream запускается до запуска таймера, но таймер заканчивается до того, как операция readStream получает свои первые данные только из-за объема работы, требуемой для внутренних операций async.
Я думаю, что из-за неблокирующем природы nodejs, как обратного вызова выполняются в «параллельно» и SetTimeout заканчивает первый и возврата (например, тайм-аут 1000 мс переключит результаты.)
Да, это правильно.
Подумайте об этом. У вас есть два мощных мегафона и действительно хороший микрофон. Вы настроили две цели, чтобы указать на мегафон и прослушать возвращаемое эхо. Одна цель, т.е. очень близкая, и одна цель находится очень далеко. Сначала вы запускаете мегафон на очень отдаленную цель, а затем сразу же взрываете мегафон у ближайшей цели. Не удивительно, что вы получаете эхо от ближней цели, даже если вы отправили его взрыв после первого, просто потому, что эхо от дальней цели занимает намного больше времени, чтобы пройти все его дополнительное расстояние и вернуться к вам. То же самое можно сказать о вашем readStream. Несмотря на то, что вы начали его сначала, он занимает намного больше времени, чем setTimeout(fn, 0)
, поэтому сначала заканчивается setTimeout()
и, таким образом, вызывает его обратный вызов.
Если выбор время важно для вас, то вам следует использовать такие инструменты, как обещания конкретно последовательность ваших операций асинхронных или ждать, пока все необходимые результаты не будут готовы.Хорошая конструкция не должна «предполагать», что одна асинхронная операция будет завершена перед другой, если только ваш код не гарантирует, что путем последовательности операций.