首页 > 解决方案 > 无法并行发出 2 个请求 - nodejs

问题描述

我有这个代码:

import http from 'http';

const longComputation = () => {
  return new Promise((resovle) => {
    console.log('started');
    let sum = 0;
    for (let j = 0; j < 10; j++) {
      for (let i = 0; i < 1e9; i++) {
        sum += i;
      }
    }
    resovle(sum);
  });
};

const server = http.createServer();

server.on('request', async (req, res) => {
  console.log('request');
  if (req.url === '/compute') {
    const sum = await longComputation();
    console.log('finished');
    return res.end(`Sum is ${sum}`);
  } else {
    res.end('Ok');
  }
});

server.listen(3000);

的目的longComputation是模拟长时间运行的任务,然后我提出两个请求:

  1. 到 /compute(执行长任务 - 需要 3 秒)
  2. 1秒后我发送到/ - 只需要返回“OK”

但是当我发出第二个请求时,服务器在第一个请求完成之前不会响应,

**这是两个请求的输出 - 您可以看到第二个请求最后打印,直到第一个处理完成。

  1. 要求
  2. 开始
  3. 完成的
  4. 要求**

为什么会这样?

标签: node.jshttpserver

解决方案


这是因为 JavaScript 是单线程的。您将需要阅读一些关于协作多任务的内容,这是 JS 使用的多任务模型。除非您明确使用工作线程(这些仍然有些新),否则在 JS 中不会并行发生任何事情。因此,您的长时间计算将停止应用程序中的所有内容,包括您想要响应第二个请求的服务器。

如果您真的需要长时间运行的计算,我会使用工作线程,或者在许多情况下,考虑在 C++ 库中实现计算(这也会更快)。或者,您可以将计算分解为许多逻辑块,并放弃块之间的控制。实现这一点的一种方法是使用setTimeout(() => processChunk(nextChunk), 1)开始下一个块。


推荐阅读