В файле node.js / Express почему иногда требуется оператор return после next (), а иногда нет? - PullRequest
0 голосов
/ 17 сентября 2018

В следующем тестовом коде проверяется req.query, чтобы увидеть, является ли его значение name = cat.Если это не так next() запускает следующую часть промежуточного программного обеспечения.Это выполняется без включения оператора return после next(), и он работает как ожидалось.

app.get('/test', (req, res, next) => {
    if (req.query.name != 'cat') {
        next();
    } 
    res.send('it was cat');
});

app.get('/test', (req, res) => {
    res.send('it was not cat');
});

Однако, когда я изменяю res.send на res.sendFile во второй части промежуточного программного обеспечения, поведение полностьюразные.

app.get('/test', (req, res) => {
    res.sendFile(__dirname + '/public/index.html');
});

После изменения res.send('it was cat'); в первом компоненте промежуточного программного обеспечения срабатывает каждый раз, независимо от значения имени.Кроме того, вторая часть промежуточного программного обеспечения никогда не срабатывает.

Это можно легко исправить, добавив return после next() в первую часть промежуточного программного обеспечения.Поведение снова становится предсказуемым.

app.get('/test', (req, res, next) => {
    if (req.query.name != 'cat') {
        next();
        return;
    } 
    res.send('it was cat');
});

app.get('/test', (req, res) => {
    res.sendFile(__dirname + '/public/index.html');
});

Почему это происходит с оператором return и без него?return необходим, когда я использую res.sendFile, но не когда я использую res.send.Я уверен, что упускаю что-то очевидное, но я не понимаю закономерность.

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

Это выполняется без включения оператора return после next() и работает как положено.

Нет, он выглядит , как будто он работает, как ожидалось, но это не так. Например, если вы получаете /test без параметра запроса или с параметром запроса, который не равен name=cat, Express выдаст сообщение об ошибке:

Error: Can't set headers after they are sent.

Я не могу воспроизвести ваш второй пример; для меня это всегда возвращает "это был кот" (в примере без return).

Общее правило для любого обработчика / промежуточного программного обеспечения Express: или должны заканчивать сам ответ (вызывая res.end, res.send, res.render, res.sendFile и т. Д.) или передать запрос, используя next. В вашем случае без return вы делаете и то и другое. Результат, по сути, будет неопределенным.

0 голосов
/ 17 сентября 2018

Когда ваш слушатель выполняет res.send('it was not cat'), вся обработка запроса происходит без удара батута.Вызов next() никогда не завершается, пока не закончится res.send('it was not cat').Таким образом, к тому времени, когда код для send('it was the cat') достигнут, ответ уже отправлен.

Но когда ваш слушатель выполняет res.sendFile(), обработка ответа является асинхронной.Файл должен быть прочитан в память, которая не блокирует ввод / вывод в узле.Обратный вызов для этого ввода / вывода помещается в очередь событий, а затем обработка продолжается.Таким образом, вызов next() возвращается, а затем send('it was the cat') выполняется.Все это еще до того, как файл будет прочитан в память.Позже, когда файл читается, код покорно пытается отправить ответ, но уже слишком поздно.

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