NodeJS自然非阻塞I / O

时间:2021-11-13 20:18:35

I read about non-blocking nature of nodeJS, and how I/O operations are non-blocking. I created a simple test to prove this

我阅读了nodeJS的非阻塞性质,以及I/O操作如何非阻塞。我创建了一个简单的测试来证明这一点

var request = require('request');
var http = require('http');
var express = require('express');

var app = express();

app.get('/test1', function (req, res) {
  res.sendStatus(httpStatus.OK);
});
app.get('/test2', function (req, res) {
  request.get('https://httpbin.org/delay/15', function () {
    res.sendStatus(httpStatus.OK);
  });
});
var server = http.createServer(app);
server.listen(3003);

module.exports = app;

That's the whole test. test1 endpoint returns OK immediately, while test2 returns OK after 15 seconds due to http request that is sent. When I call test2 and immediately after that call test1, the response for test1 is returned after 15 seconds. I would expect if I/O operations are non-blocking that response for test1 is going to be returned immediately.

这就是整个测试。test1端点立即返回OK,而test2由于发送的http请求在15秒后返回OK。当我调用test2并且在调用test1之后,test1的响应在15秒后返回。如果I/O操作没有阻塞,那么test1的响应将立即返回。

What am I missing?

我缺少什么?

UPDATE:

更新:

I was sending requests using Postman with Interceptor turned on. In that case Postman can send only one request to a single host at a time.

我在用打开拦截器的邮递员发送请求。在这种情况下,邮递员每次只能向单个主机发送一个请求。

So nodeJS non-blocking I/O works perfectly fine, the issue was related to Postman Interceptor plugin.

所以nodeJS非阻塞I/O运行良好,问题与Postman拦截器插件有关。

1 个解决方案

#1


2  

Those operations are non-blocking and this is demonstrated by your code example - I only fixed it in one place because it wasn't working with httpStatus being undefined - maybe that was your problem. See:

这些操作是非阻塞的,这在您的代码示例中得到了演示——我只在一个地方修复了它,因为它没有使用未定义的httpStatus——这可能是您的问题。看到的:

var request = require('request');
var http = require('http');
var express = require('express');

var app = express();

app.get('/test1', function (req, res) {
  res.sendStatus(200);
});
app.get('/test2', function (req, res) {
  request.get('https://httpbin.org/delay/15', function () {
    res.sendStatus(200);
  });
});
var server = http.createServer(app);
server.listen(3003);

module.exports = app;

And run it:

并运行:

time curl http://localhost:3003/test1
OK
real    0m0.015s
user    0m0.007s
sys 0m0.004s

and:

和:

time curl http://localhost:3003/test2
OK
real    0m10.466s
user    0m0.000s
sys 0m0.014s

In fact you can even see that you can request the long running endpoint multiple times concurrently, and all responses will be printed at the same time:

事实上,您甚至可以看到您可以同时多次请求长运行的端点,并且所有的响应将同时被打印出来:

curl http://localhost:3003/test2 &
curl http://localhost:3003/test2 &
curl http://localhost:3003/test2 &
OKOKOK

which proves that not only the /test1 endpoint is not blocking but also that the /test2 endpoint is not blocking either.

这证明不仅/test1端点没有阻塞,而且/test2端点也没有阻塞。

#1


2  

Those operations are non-blocking and this is demonstrated by your code example - I only fixed it in one place because it wasn't working with httpStatus being undefined - maybe that was your problem. See:

这些操作是非阻塞的,这在您的代码示例中得到了演示——我只在一个地方修复了它,因为它没有使用未定义的httpStatus——这可能是您的问题。看到的:

var request = require('request');
var http = require('http');
var express = require('express');

var app = express();

app.get('/test1', function (req, res) {
  res.sendStatus(200);
});
app.get('/test2', function (req, res) {
  request.get('https://httpbin.org/delay/15', function () {
    res.sendStatus(200);
  });
});
var server = http.createServer(app);
server.listen(3003);

module.exports = app;

And run it:

并运行:

time curl http://localhost:3003/test1
OK
real    0m0.015s
user    0m0.007s
sys 0m0.004s

and:

和:

time curl http://localhost:3003/test2
OK
real    0m10.466s
user    0m0.000s
sys 0m0.014s

In fact you can even see that you can request the long running endpoint multiple times concurrently, and all responses will be printed at the same time:

事实上,您甚至可以看到您可以同时多次请求长运行的端点,并且所有的响应将同时被打印出来:

curl http://localhost:3003/test2 &
curl http://localhost:3003/test2 &
curl http://localhost:3003/test2 &
OKOKOK

which proves that not only the /test1 endpoint is not blocking but also that the /test2 endpoint is not blocking either.

这证明不仅/test1端点没有阻塞,而且/test2端点也没有阻塞。