Node.js同一路由多请求为何顺序执行?及路由事件循环疑问
Node.js路由请求串行问题分析
问题描述
我在Node.js应用中定义了两个路由,代码如下:
/ 路由代码
router.get("/", async (req, res, next) => { console.log("Service health request.", req.ip, new Date()); let response = { success: true, message: "Service is running!!" }; await wait(10000); return res.json(response); }); const wait = (milliseconds) => { return new Promise(resolve => setTimeout(resolve, milliseconds)); }
/status 路由代码
router.get("/status", async (req, res, next) => { console.log("Any other route request."); let response = { success: true, data: {} }; await wait(10000); return res.json(response); });
现象:
- 并发向
/路由发起请求时,请求被顺序执行:第一个耗时10秒,第二个20秒,第三个30秒,以此类推。 - 同时请求
/status路由时,该请求能无延迟被处理。
疑问:
- 为何
/路由的请求会被顺序执行而非并发处理? - Node.js是否会为应用中的每个路由创建单独的事件循环或调用栈?
解答
1. /路由请求串行的根本原因:客户端请求限制
你看到的串行执行不是Node.js的问题,而是测试时使用的客户端(比如浏览器)的默认限制导致的:
- 主流浏览器(如Chrome、Firefox)会对同一域名下的同一URL的GET请求做串行发送限制,目的是避免重复请求、利用缓存或减少服务器压力。当你在同一个浏览器标签页多次请求
/路由时,浏览器会等待前一个请求完成后再发送下一个,所以看起来是串行执行,耗时累加。 - 而
/status是不同的URL,浏览器不会触发这个串行限制,会并行发送请求,Node.js也能正常并行处理。
验证方式:
用Postman、curl等工具并发请求/路由,或者用不同的浏览器窗口/标签页发送/路由请求,你会发现每个请求都耗时约10秒,而非累加——这才是Node.js实际的处理状态。
Node.js的处理逻辑:
Node.js是单线程事件循环模型,当请求进入/路由的async函数后,执行到await wait(10000)时,会将这个Promise挂起并让出事件循环线程,此时Node.js可以立即处理其他进来的请求(不管是同一个路由还是不同路由)。所以Node.js本身是支持该路由的并发请求处理的。
2. Node.js不会为每个路由创建单独的事件循环或调用栈
整个Node.js进程只有一个主线程、一个事件循环和一个全局调用栈:
- 所有路由的请求都会进入同一个事件循环排队等待处理。
- 调用栈是全局共享的,当同步代码执行时会占用调用栈,异步操作(比如
setTimeout)完成后,其回调会被放入事件队列,等待调用栈清空后再被执行。 - 路由只是请求的分发规则,不会改变Node.js的核心运行模型。
内容的提问来源于stack exchange,提问作者Ankur Mahajan
相关产品推荐
相关产品推荐

