Почему я могу выполнить код после "res.send"?
Мне интересно, что такое механика, стоящая за поведением следующего кода:
res.send(200, { data: 'test data' });
console.log('still here...');
Я понимаю, что res.send
не возвращает функцию, но закрывает соединение/завершает запрос. Это может объяснить, почему я все еще могу выполнить код после команды res.send
(я просмотрел экспресс-источник и, похоже, не является асинхронной функцией).
Есть ли что-то еще в игре, которые могут отсутствовать?
Ответы
Ответ 1
Sure end
завершает HTTP-ответ, но он не делает ничего особенного для вашего кода.
Вы можете продолжать делать другие вещи даже после того, как вы закончили ответ.
Однако вы не можете делать ничего полезного с помощью res
. Поскольку ответ завершен, вы не можете записать на него больше данных.
res.send(...);
res.write('more stuff'); // throws an error since res is now closed
Это поведение отличается от других традиционных фреймворков (PHP, ASP и т.д.), которые выделяют поток для HTTP-запроса и завершают поток, когда ответ завершен. Если вы вызываете эквивалентную функцию, например ASP Response.End
, поток завершается, и ваш код перестает работать. В node нет потока для остановки. req
и res
больше не будут запускать события, но код в ваших обратных вызовах может продолжать работать (пока он не пытается вызвать методы на res
, для которых требуется, чтобы действительный ответ был открытым).
Ответ 2
Изменить: Я больше не делаю то, что объяснено ниже, так как вы не должны возвращать значение, когда в этом нет необходимости. Это делает ваш код менее читаемым и выглядит взломанным. Вместо этого я предлагаю отделить оператор return от res.send()
. @slavafomin объяснил это хорошо в комментариях.
Простым способом остановки выполнения функции и отправки ответа в одно время является
return res.send('500', 'Error message here');
Это позволяет использовать короткие инструкции if
для обработки таких ошибок, как:
if (err) {
return res.send('500', 'Error message here');
}
Точный возврат функции res.send
- это объект, который, кажется, содержит все состояние соединения после его окончания (запрос, статус, заголовки и т.д.), но это должно быть неважно, поскольку вы не будете что-нибудь с ним делать.