Express. js: отправить ответ и выполнить фоновую задачу - PullRequest
0 голосов
/ 08 мая 2020

В Express. js Я хочу выполнить задачу после отправки ответа.

Однако я хочу, чтобы время отклика было как можно быстрее. Мне не нужно возвращать результаты этой задачи клиенту, поэтому я пытаюсь вернуть ответ немедленно.

Задача не загружает процессор, тогда событие l oop isn ' t заблокирован этой задачей.

Итак, это моя фоновая задача:

function backgroundTask() {
   return new Promise(resolve => setTimeout(() => {
      console.log("backgroundTask finished");
      resolve();
   }, 1000));
}

Моя первая попытка - вызвать функцию backgroundTask напрямую:

app.post('/messages', async function (req, res) {
  res.status(200).send({ success: true });
  performBackgroundTasks();
});

вторая попытка - вызвать функцию backgroundTask в setTimeout ():

app.post('/messages', async function (req, res) {
  res.status(200).send({ success: true });
  setTimeout(() => performBackgroundTasks(), 0);
});

Возникает вопрос: каков наилучший метод обеспечения того, чтобы ответ отправлялся клиенту, а задача выполнялась в фоновом режиме?

БОКОВОЕ ПРИМЕЧАНИЕ: я знаю, что «лучший метод» - это использовать рабочие потоки, но мне просто нужен простой способ для выполнения фоновой задачи.

Ответы [ 4 ]

2 голосов
/ 08 мая 2020

Вы можете превратить функцию в промежуточное ПО и вызвать next () после вашего ответа

1 голос
/ 08 мая 2020

Вы можете использовать событие finish:

app.use((req, res, next) => {
    res.on('finish', () => {
        console.log('Response has been sent!')
        performBackgroundTasks();
    })
    next()
})
1 голос
/ 08 мая 2020

Я рад, что вы упомянули, что лучший метод - создать рабочий поток, потому что это так. Я считаю, что вы пытаетесь сделать то, чего быть не должно. отправка вашего res из express предназначена для окончательной остановки этого процесса и должна содержать подробную информацию об успехе всей работы, поэтому дальнейшее выполнение лишит ваше приложение возможности сделать это. По крайней мере, без повторного вызова API к вашему dB после возврата к интерфейсу.

, если второй шаг не важен для ваших пользователей, почему бы не вернуться с первым разрешением и не запустить еще один express вызов из вашего обещания return на главной странице?

Извините, Я уверен, что у вас есть для этого веская причина, возможно, вы сможете уточнить, почему вам нужно идти именно по этому маршруту ...

1 голос
/ 08 мая 2020

И первая, и вторая попытки идеально подходят для вашего варианта использования. Если ваша задача не требует интенсивного использования ЦП, использование Worker Threads даже не лучше, чем оба подхода.

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