简体   繁体   English

express.router()的路由是否同步?

[英]Is the routing of express.router() synchronous?

This has been baffling me... This following test shows that requests are being received asynchronously, responded to asynchronously, yet all requests are first received, then responded to... Given the following 3 files: 这让我感到困惑...以下测试显示请求被异步接收,异步响应,但是首先接收所有请求,然后响应...给定以下3个文件:

package.json 的package.json

{
    "name": "express-router-sync-test",
    "version": "1.0.0",
    "description": "Testing if express router has sync aspect",
    "scripts": {
        "start": "node server.js"
    },
    "dependencies": {
        "body-parser": "1.16.0",
        "express": "4.14.1",
        "request": "2.79.0"
    }
}

server.js server.js

const express = require('express');
const bodyParser = require('body-parser');
const router = express.Router();
const request = require('request');

// Create our Express application
let app = express();

let port = 1111;

// body parser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.use(router);

// Start the server
app.listen(port);
console.log('Server listening on port ' + port + '.');


router.get('/', _get);
router.post('/test', _test);

function _test(req, res) {
    console.log('starting to process request # ', req.body.requestNumber);
    request({
        method: 'GET',
        url: 'http://localhost:1111'
    }, (err, response, body) => {
        console.log('process # ' +  req.body.requestNumber + ' has ended');
    });
}

function _get(req, res) {
    res.json({ success: true });
}

test.js test.js

const request = require('request');

let i;
let len = 500;
let options = {
    method: 'POST',
    url: 'http://localhost:1111/test'
}

for (i = 0; i < len; i++) {
    options.form = { requestNumber: i + 1 };
    request(options, (err, response, body) => {
        if (err) console.log(err);
        if (response) console.log(body)
    }); 
}

Given a dir structure of: 给定一个目录结构:

app/
--package.json
--server.js
--test.js

Take the following steps to reproduce the test: 请执行以下步骤来重现测试:

  • in a terminal, navigate to the app dir and run npm install 在终端中,导航到应用程序目录并运行npm install
  • run node server.js 运行node server.js
  • open another terminal, navigate to app dir and run node test.js 打开另一个终端,导航到应用程序目录并运行node test.js

If you look at the output of the server.js terminal, you will note that all "starting processes" loggings are grouped together, but in an asynchronous order. 如果查看server.js终端的输出,您会注意到所有“启动进程”日志记录都以异步顺序分组在一起。 You will also note that all "process ended" loggings are grouped together, but also in an asynchronous order. 您还将注意到,所有“进程结束”日志记录都被分组在一起,但是也以异步顺序分组。

I now ask two questions: 我现在问两个问题:

  • Why are the responses delayed until after all requests have been received? 为什么将响应延迟到收到所有请求之后?
  • Is this happening because I'm flooding myself with requests? 发生这种情况是因为我正在向自己发送大量请求吗?

Any information would be greatly appreciated. 任何信息将不胜感激。

EDIT: here is an example log of this test run with 50 requests instead of 500. You'll notice that no request is responded to until all requests have been received. 编辑:这是此测试运行的示例日志,其中包含50个请求而不是500个请求。您会注意到,直到收到所有请求后,才会响应任何请求。 The more requests you send, the longer you wait for the first response. 您发送的请求越多,等待第一个响应的时间就越长。

starting to process request #  1
starting to process request #  2
starting to process request #  3
starting to process request #  4
starting to process request #  5
starting to process request #  6
starting to process request #  9
starting to process request #  8
starting to process request #  7
starting to process request #  10
starting to process request #  12
starting to process request #  11
starting to process request #  13
starting to process request #  17
starting to process request #  16
starting to process request #  15
starting to process request #  14
starting to process request #  21
starting to process request #  19
starting to process request #  20
starting to process request #  18
starting to process request #  22
starting to process request #  23
starting to process request #  25
starting to process request #  24
starting to process request #  27
starting to process request #  28
starting to process request #  26
starting to process request #  32
starting to process request #  31
starting to process request #  30
starting to process request #  29
starting to process request #  36
starting to process request #  35
starting to process request #  33
starting to process request #  34
starting to process request #  40
starting to process request #  38
starting to process request #  39
starting to process request #  37
starting to process request #  44
starting to process request #  42
starting to process request #  43
starting to process request #  41
starting to process request #  45
starting to process request #  46
starting to process request #  47
starting to process request #  49
starting to process request #  48
starting to process request #  50
process # 1 has ended
process # 2 has ended
process # 4 has ended
process # 3 has ended
process # 5 has ended
process # 6 has ended
process # 9 has ended
process # 8 has ended
process # 11 has ended
process # 12 has ended
process # 10 has ended
process # 7 has ended
process # 13 has ended
process # 17 has ended
process # 15 has ended
process # 16 has ended
process # 14 has ended
process # 21 has ended
process # 22 has ended
process # 18 has ended
process # 20 has ended
process # 19 has ended
process # 27 has ended
process # 24 has ended
process # 25 has ended
process # 23 has ended
process # 31 has ended
process # 32 has ended
process # 26 has ended
process # 28 has ended
process # 30 has ended
process # 29 has ended
process # 34 has ended
process # 35 has ended
process # 33 has ended
process # 36 has ended
process # 40 has ended
process # 38 has ended
process # 39 has ended
process # 37 has ended
process # 44 has ended
process # 42 has ended
process # 46 has ended
process # 45 has ended
process # 41 has ended
process # 43 has ended
process # 47 has ended
process # 50 has ended
process # 48 has ended
process # 49 has ended

This following test shows that requests are being received asynchronously, responded to asynchronously, yet all requests are first received, then responded to... 以下测试显示请求是异步接收,异步响应的,但是首先接收所有请求,然后响应...

It's not clear what is the surprise here. 目前尚不清楚这里有什么惊喜。 That the requests are first received and then responded to? 首先收到请求,然后响应? It wouldn't make much sense to respond to a request before it is received. 在接收到请求之前响应并没有多大意义。

Since this is a very general question then maybe I'll add some general info. 由于这是一个非常笼统的问题,所以也许我会添加一些常规信息。 First of all asynchronously doesn't necessarily mean out of order, if that is what you assume. 首先,如果您假设那样的话,异步不一定意味着乱序。 Operations can be processed asynchronously and in order or out of order, this is irrelevant to the concurrency model being used. 可以异步地,有序地或无序地处理操作,这与所使用的并发模型无关。

Now, generally speaking every function that returns a value (unless that value is a promise) works synchronously by necessity, just because it cannot return anything that it doesn't have. 现在,通常来说,每个返回值的函数(除非该值是一个promise)都必须根据需要同步工作,只是因为它无法返回它没有的任何东西。 In that sense the promise itself is actually created and returned synchronously. 从这个意义上说,承诺本身实际上是创建并同步返回的。 What is done asynchronously is the resolution of the promise. 异步完成的是承诺的解决。

Every function that takes a callback usually works asynchronously but it doesn't have to. 每个需要回调的函数通常都是异步工作的,但并非必须如此。 The callback can be called synchronously and it sometimes is, like in the callback to the .map() method of arrays and strings. 回调可以同步调用,有时也可以调用,就像在数组和字符串的.map()方法的回调中一样。 Every function that returns a promise should work asynchronously but it's also possible to resolve the promise synchronously before returning it. 每个返回承诺的函数都应该异步工作,但是也可以在返回之前同步解析承诺。

The point is that being synchronous and asynchronous is something quite different from the order of execution and it also depends on whether you use promises or continuation passing style. 关键是同步和异步与执行顺序有很大不同,它还取决于您使用诺言还是连续传递样式。

For anyone else who comes across this behavior and finds it curious... This is happening because the requests are coming in so quickly that NodeJS is "stuck" in the poll phase of it's Event Loop . 对于遇到这种行为并感到好奇的其他人...之所以发生这种情况是因为请求进入的速度如此之快,以至于NodeJS陷入了Event Loop的轮询阶段。

Here is some NodeJS documentation pertaining to the Event Loop and the Polling phase . 这是一些与事件循环轮询阶段有关的NodeJS文档。

Pertinent information in link : "If the poll queue is not empty, the event loop will iterate through its queue of callbacks executing them synchronously until either the queue has been exhausted, or the system-dependent hard limit is reached." 链接中的相关信息 :“如果轮询队列不为空,则事件循环将迭代通过其同步执行它们的回调队列,直到该队列用尽或达到与系统相关的硬限制为止。”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM