Nodejs http模块,请求到来后执行的回调函数,每次请求会被执行两次吗?

Nodejs http模块,请求到来后执行的回调函数,每次请求会被执行两次吗?

RT,为什么这段代码,第一次请求输出2,第二次开始就是递增2了?? 第一次输出2是正常的,因为自增1,从第二次开始就是 4 6 8 10。。。。。why?

var http = require('http');
var i = 1;
http.createServer(function(req, res){
    i++;
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.end(i + '');
}).listen(3000);

4 回复

针对你的问题,我们来分析一下你提供的代码,并解释为什么会出现这种现象。首先,我们需要理解 http.createServer 方法的工作原理以及 i 变量的作用域。

代码分析

var http = require('http');
var i = 1;

http.createServer(function(req, res) {
    i++;
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end(i + '');
}).listen(3000);

问题描述

你提到,第一次请求时输出 2 是正常的,但从第二次开始输出结果变成了 4, 6, 8 等等。这表明每次请求时,i 的值似乎被累加了两次。

原因分析

实际上,问题不在于请求是否被执行了两次,而是因为 i 变量是一个全局变量,每次请求都会修改它。具体来说,每次请求到达时,i 都会增加 1 并返回给客户端,然后在下一次请求中继续增加 1。

示例解释

  • 第一次请求i 初始值为 1,请求时 i++ 后变为 2,然后输出 2
  • 第二次请求i 已经是 2,请求时 i++ 后变为 3,然后输出 3
  • 第三次请求i 已经是 3,请求时 i++ 后变为 4,然后输出 4

因此,输出结果实际上是 2, 3, 4, 5, … 这样递增的。

解决方案

如果你希望每次请求都输出一个新的序列号,可以考虑使用一个闭包或者将 i 放在一个局部作用域内。例如:

var http = require('http');

function createServer() {
    var i = 1; // 局部变量,每次请求时重新初始化
    return http.createServer(function(req, res) {
        i++;
        res.writeHead(200, { 'Content-Type': 'text/html' });
        res.end(i + '');
    });
}

createServer().listen(3000);

这样,每次请求时 i 都会在每次请求时重新初始化,确保每次请求的计数器独立。

总结

你的问题核心在于 i 是一个全局变量,每次请求都会修改它。通过将 i 放在一个局部作用域内,可以避免这种累加问题。希望这能帮助你更好地理解 Node.js 中的 HTTP 模块和变量作用域。


浏览器访问的??

浏览器会默认访问两次…请求favicon.ico …

把req.url打印出来果然如此,多谢

在你提供的代码中,i变量是在全局作用域中定义的。每次HTTP请求到来时,i变量会递增并输出当前的值。因此,在第一次请求时,i的初始值为1,递增后变为2,所以输出2。

从第二次请求开始,i已经不再是从1开始递增,而是基于前一次请求后的值继续递增。这导致每次请求输出的值都会增加2。例如,如果第一次请求后i变成2,则第二次请求时i变为3,输出4;第三次请求时i变为4,输出6,依此类推。

如果你希望每次请求的计数独立递增,可以将计数器重置或使用局部变量。以下是修改后的代码示例:

var http = require('http');

http.createServer(function(req, res){
    var i = 1; // 在回调函数内部定义i,每次请求都会重新初始化为1
    i++;
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.end(i + '');
}).listen(3000);

在这个修改后的版本中,每次请求都会创建一个新的局部变量i,并将它初始化为1。这样每次请求输出的值都将从2开始,而不是基于上一次请求的结果。

如果你确实需要一个全局计数器(比如跟踪总请求数),可以单独定义一个变量来实现这个功能。

回到顶部