2016-11-08 140 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.685ms内完成,但响应需要2500ms才能完成。)

有没有办法立即发送响应并完成其他任务而无需客户端等待/挂起? (在我的情况下,客户端不能进行多个API调用。)

+0

你应该工作得很好吗?只要响应在服务器上结束,那么之后会发生什么情况不应该影响浏览器。 – adeneo

+0

@adeneo我已经在本地使用CURL测试了它,并且响应需要在“200-15000ms”之间。当我注释掉'performComplexTasks(body)'时,响应花费大约10ms。所有其他API端点(没有长时间任务)似乎更快。这可能是因为一个独立的问题(即我的服务器CPU使用率,而不是正确处理'req','res')?如果是这样,你有什么建议我应该开始调查? –

+0

@adeneo另外,万一它很重要,这个端点将被另一个服务器(而不是浏览器)调用。 –

回答

1

我说得对,您试图在performComplexTasks中执行CPU密集型作业吗?如果是这样,那么事件循环被该任务锁定,并且新的请求正在等待,直到作业完成。

在node.js中执行与http服务器相同的进程中的“复杂”任务是不好的做法。考虑使用后台工作人员,队列或类似的东西。

请参见本主题的详细信息:Node.js and CPU intensive requests

+0

这是真的,但OP的代码应该结束响应,然后进行阻塞工作,这样新的请求将不得不等待等等,它不应该阻止当前已经收到响应的请求。 – adeneo

+0

@No Danger当您刚开始使用快递应用程序时,第一次请求POST /消息怎么样?它运行速度快吗? – teq

+0

@不危险你确定其他端点不受影响吗?你打电话给POST /消息之前和之后你有没有试过打电话给他们?还要确保performComplexTasks函数没有任何“全局”变量/锁(在请求之间共享) – teq

0

如果你的工作是不是超级CPU-激烈,你能容忍主服务器的线程上的一些工作,然后只用等待打破执行,以便请求可以正确发送。您可以使用setTimeoutawait

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"); 
}