2016-11-08 4 views
3

В Node.js (который я новичок) Я пытаюсь выполнить ряд задач после получения ответа. Тем не менее, я хочу сделать время ответа как можно быстрее. Мне не нужно возвращать результаты этих задач клиенту, поэтому я пытаюсь немедленно вернуть ответ.Отправить ответ и продолжить выполнение задач Express | Node.js

Моя текущая реализация примерно:

var requestTime = Date.now; 

app.post('/messages', function (req, res) { 
    console.log("received request"); 

    // handle the response 
    var body = res.body; 
    res.send('Success'); 
    res.end(); 
    console.log("sent response"); 

    performComplexTasks(body) 
}) 

function performComplexTasks(body){ 
    // perform data with body data here; 
    console.log("finished tasks:", Date.now()-requestTime, "ms"); 
} 

// -------LOG----------- 
// received request 
// POST /api/messages 200 3.685 ms - 59 
// sent response 
// finished tasks: 2500ms 

Клиент делает запрос кажется дотянуть до performComplexTasks() закончена. (POST заканчивается в 3.685 мс, но ответ занимает 2500 мс.)

Есть ли способ отправить ответ немедленно и выполнить другие задачи, не ожидая, что клиент будет ждать/висеть? (В моем случае клиент не может совершать несколько вызовов API.)

+0

Что вам нужно, чтобы нормально работать? До тех пор, пока ответ будет завершен на сервере, что происходит после этого не должно влиять на браузер. – adeneo

+0

@adeneo Я тестировал это, используя CURL локально, и ответ берется между '200-15000ms'. Когда я комментирую 'performComplexTasks (body)' ответ занимает около 10 мс. Все остальные конечные точки API (без длинных задач) кажутся более быстрыми. Может ли это быть из-за независимой проблемы (т. Е. С использованием моего центрального процессора вместо правильной обработки 'req',' res')? Если да, есть ли у вас предложения о том, где я должен начать расследование? –

+0

@adeneo Кроме того, в случае, если это имеет значение, эта конечная точка будет вызываться другим сервером (а не браузером). –

ответ

1

Я прав, что вы пытаетесь выполнить работу с ЦП в performComplexTasks? Если это так, то цикл события блокируется этой задачей, и новые запросы ждут, пока задание не будет завершено.

Неправильная практика в node.js для выполнения сложных задач в том же процессе, что и HTTP-сервер. Рассмотрите возможность использования фоновых работников, очередей или чего-то подобного.

Смотрите эту тему Подробности: Node.js and CPU intensive requests

+0

Это правда, но код OP должен завершить ответ, а затем выполнить блокировку, чтобы новые запросы должны были ждать и т. Д., Это не должно задерживать текущий запрос, который уже получил ответ. – adeneo

+0

@No Danger Что касается самого первого запроса POST/сообщений, когда вы только что начали экспресс-приложение? Он работает быстро? – teq

+0

@No Danger Вы уверены, что другие конечные точки не затронуты? Вы пытались позвонить им до и после того, как вы вызвали POST/сообщения? Также убедитесь, что функция executeComplexTasks не имеет никаких «глобальных» переменных/блокировок (разделенных между запросами) – teq

0

Если ваша работа не супер-CPU-интенсивный и вы можете терпеть некоторые работы на главном потоке сервера, а затем просто использовать ждать, чтобы прервать выполнение так, что запрос может быть отправлено правильно. Вы можете использовать setTimeout или await.

var requestTime = Date.now; 

app.post('/messages', async function (req, res) { 
    console.log("received request"); 

    // handle the response 
    var body = res.body; 
    res.status(200).send({ success: true }); 
    console.log("sent response"); 

    // Method 1: 
    await performComplexTasks(body) 

    // Method 2: 
    setTimeout(() => performComplexTasks(body), 0); 
}) 

async function performComplexTasks(body){ 
    // perform data with body data here; 
    console.log("finished tasks:", Date.now()-requestTime, "ms"); 
} 
Смежные вопросы