发送响应并继续执行任务 Node.js

No *_*ger 10 javascript asynchronous 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
Run Code Online (Sandbox Code Playgroud)

发出请求的客户端似乎挂起,直到performComplexTasks()完成。(POST完成时间为3.685ms,但响应需要2500ms才能完成。)

有没有一种方法可以立即发送响应并完成其他任务而无需客户端等待/挂起?(就我而言,客户端无法进行多个API调用。)

小智 14

如果您的工作不是超 CPU 密集型的并且您可以容忍主服务器线程上的一些工作,那么只需使用await中断执行以便可以正确发送请求。您可以使用setTimeoutawait

// This line is wrong too - ask a separate question if needed
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){
   // The line below is required if using the `await` method -
   // it breaks execution and allows your previous function to
   // continue, otherwise we will only resume the other function after
   // this function is completed.
   await new Promise(resolve => setTimeout(resolve, 1));

   // perform data with body data here;
   console.log("finished tasks:", Date.now()-requestTime, "ms");
}
Run Code Online (Sandbox Code Playgroud)

这并不是一个很好的解决方案,您需要使用工作线程进行长时间的操作。


teq*_*teq 8

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

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

有关详细信息,请参阅此主题:Node.js 和 CPU 密集型请求