Я пытаюсь выяснить, каков наилучший / быстрый способ отправить ответ от expressjs, а затем выполнить лог или выполнять длинные действия на сервере, не задерживая ответ клиенту.
Лучший способ сделать это - позвонить по номеру longAction()
только тогда, когда экспресс сообщит вам, что ответ отправлен. Поскольку объект ответа является потоком, вы можете использовать событие finish
в этом потоке, чтобы узнать, когда все данные из потока были сброшены в базовую ОС.
Из документации для записи потока :
Событие finish заканчивается после вызова метода stream.end (), и все данные сбрасываются в базовую систему.
Вот как вы можете использовать это в вашем конкретном коде:
function myfunction (req, res) {
res.render(MYPATH, 'index.response.html'), {title: 'My Title'}, (err, html) => {
if (err) {
res.status(500).json({'error':'Internal Server Error. Error Rendering HTML'});
}
else {
res.on('finish', () => {
longAction();
});
res.send(html);
}
});
}
Для более подробного объяснения события finish
вы можете начать с просмотра Express-кода для res.send()
и увидеть, что в итоге вызывается res.end()
для фактической отправки данных. Если вы затем посмотрите на документацию для .end()
в потоке для записи, он скажет следующее:
Вызов метода writable.end () сигнализирует о том, что в Writable больше не будут записываться данные. Необязательные аргументы блока и кодирования позволяют записать один последний дополнительный блок данных непосредственно перед закрытием потока. Если предусмотрено, дополнительная функция обратного вызова присоединяется в качестве прослушивателя для события финиша.
Итак, так как Express не предоставляет доступ к обратному вызову, который предлагает .end()
, мы просто слушаем событие finish
, чтобы получить уведомление, когда поток завершит отправку своего последнего бита данных.
Обратите внимание, в вашем коде также есть опечатка, где re.status(500)
должно быть res.status(500)
.