Я наткнулся на этот маршрут express.js, который является частью небольшого примера в официальном репо, демонстрирующем, как обрабатывать ошибки, посмотрите:

app.get('/next', function(req, res, next) {
  process.nextTick(function() {
    next(new Error('oh no!'));
  });
});

Что я понимаю о process.nextTick(), так это то, что он заставляет фрагменты кода выполняться асинхронно. Но вот что сбивает с толку: не являются ли обработчики маршрутов по умолчанию асинхронными? почему этому коду нужно было использовать process.nextTick() в обработчике маршрута, если по умолчанию они выполняются асинхронно? Просмотр всего кода в репо, которое я привел выше, может прояснить мой вопрос, не волнуйтесь, все репо - это 20 строк кода.

1
segmentationfaulter 24 Фев 2016 в 10:50

2 ответа

Лучший ответ

Из кода, который вы нам показали, нет причин использовать process.nextTick() в этом примере кода.

Код можно было просто вызвать напрямую next(new Error('oh no!')) вот так:

app.get('/next', function(req, res, next) {
    next(new Error('oh no!'));
});

process.nextTick() используется, когда вы хотите отложить выполнение чего-либо до момента, пока не будет запущена остальная часть кода обработчика событий. Но в показанном вами примере в обработчике событий нет другого кода, поэтому запускать больше нечего - поэтому практических причин для использования здесь process.nextTick() нет.

Лучшее, что я могу догадаться, это то, что они просто показывают пример кода, который иллюстрирует, что next() может вызываться асинхронно через некоторое время в будущем, если это необходимо, и его не нужно вызывать синхронно. С таким же успехом они могли бы использовать fs.readFile() или setTimeout(), оба из которых имеют асинхронные обратные вызовы, а затем вызвали next() из этих обратных вызовов - все, чтобы продемонстрировать, что вы просто вызываете next() когда ваша операция будет завершена.

2
jfriend00 24 Фев 2016 в 08:29

Вам нужно осознать тот факт, что узел не является действительно асинхронным. Каждый проход через цикл событий будет выполняться до завершения. Конечно, вы устраиваете вещи (с обратными вызовами, обещаниями или событиями) так, чтобы каждый прогон до завершения был очень коротким и нигде не блокировался, но во время прогона больше ничего не происходит. Это не похоже на настоящую многопроцессорную / многозадачную операционную систему, такую как Linux, где поток может быть прерван в любой момент.

Истинная многозадачность - это сложно, потому что что бы вы ни делали, вы учитываете тот факт, что работа может быть прервана в любое время, тогда как node упрощает задачу, поскольку вы можете быть уверены, что ваш текущий поток дойдет до конца.

Так что, если у вас есть что-то, что вы хотите обеспечить запуск позже, или, как я думаю, показывает этот пример, вам не нужно, чтобы это запускалось немедленно, и было бы лучше уйти с дороги и позволить другим частям системы сказать свое слово, тогда вы вызываете process.nextTick ().

0
akc42 24 Фев 2016 в 08:02