Nodejs res.json() 后,后面的代码还会继续执行么?

Nodejs res.json() 后,后面的代码还会继续执行么?

这是登录的过程,如果user为空返回{“status”:-1,“msg”:“Username Not exists”}

现在user为null的时候,会报错,TypeError: Cannot read property 'password' of null

很明显是继续执行了 if(user.password != password) 这句话。

但是如果我把密码判断这三行注释掉,却不会继续执行res.json({"status":1}) .

我就非常困惑了,res.json() 后面的代码到底是执行还是不执行啊 ??

User.get(username,function(err,user){
    if(!user){
        console.log("Error");
        res.json({"status":-1,"msg":"Username Not exists"});
    }
if(user.password != password){
    res.json({"status":-1,"msg":"Password Error"});
}

res.json({"status":1});

})


14 回复

在Node.js中使用res.json()方法后,服务器端的代码通常会认为响应已经完成,并且不会继续执行后续代码。然而,具体行为取决于你的应用程序结构和中间件处理方式。

示例代码分析

考虑以下登录过程的代码片段:

User.get(username, function(err, user) {
    if (err) {
        console.error(err);
        res.status(500).json({ status: -2, msg: "Internal Server Error" });
        return; // 防止继续执行
    }

    if (!user) {
        console.log("Error");
        res.json({ status: -1, msg: "Username Not exists" });
        return; // 防止继续执行
    }

    if (user.password !== password) {
        res.json({ status: -1, msg: "Password Error" });
        return; // 防止继续执行
    }

    res.json({ status: 1 });
});

解释

  1. 错误处理:首先检查是否有错误发生(例如数据库查询失败)。如果有错误,返回一个500状态码,并结束响应。
  2. 用户名不存在:如果用户不存在(即usernull),返回一个错误信息,并结束响应。
  3. 密码错误:如果密码不匹配,返回一个密码错误信息,并结束响应。
  4. 成功登录:如果所有检查都通过,返回成功登录的信息。

关键点

  • 每次调用res.json()之后,都应该使用return语句来防止继续执行后续代码。
  • res.json()方法实际上会调用res.end()或类似的结束响应的方法,因此在它之后的代码默认不会执行。

可能遇到的问题

如果你没有在每次调用res.json()之后添加return语句,可能会导致逻辑错误,如你所描述的TypeError: Cannot read property 'password' of null错误。

总结

为了确保代码的正确性和可读性,在每次调用res.json()之后添加return语句是一个好习惯。这样可以明确表示响应已经结束,避免不必要的错误。


这个问题很难么。。大神们给个力点醒我啊!

加个 return

在res.json({“status”:1});前加console.log(‘333333’);看看能不能输出333333,如果能 说明它会执行,看看是不是其他地方有错误

最底部加上console.log(‘xx’)是可以输出的,但是在express的send和json输出响应体的时候,如果有两个连续的输出,默认只是第一个,如果在原生node的处理,加入res.write()里面的字节数在ff中没超过0.5kb和在chrome中没有超过1kb都会拼接起来的

最后一句代码是会运行的,但是内容不会写回。这个要从express源码查原因,res.json最后调用的是res.send返回,我摘入了一些res的源码内容:

...
var res = module.exports = {
  __proto__: http.ServerResponse.prototype
};
...
res.send = function(body){
...
  // respond
  this.end(head ? null : body);
  return this;
};

最后是通过ServerResponse.prototype.end返回的,可以预计这个方法是会把socket给关闭(没有去继续追源码了,要详细了解可以去追查nodejs的源码),这就是为什么后面一句res.json不会返回(注意代码是运行的!)。

所以最好的写法是在前两个res.json后加上return

if(!user){
    console.log("Error");
    res.json({"status":-1,"msg":"Username Not exists"});
    return;
}

if(user.password != password){ res.json({“status”:-1,“msg”:“Password Error”}); }

我目前是这么办的。 加return 总感觉有点繁琐 = =! 人懒

嗯,他应该是继续向下执行的。 我感觉res.json() 要是有return的功效就爽多了

Yes 现在是这么办的 ^ .^

原来是这样,受教了

现在就是加了return。 看你贴的源码,res.send() 貌似是有return的功效啊。

send貌似发送json也是可行的,下班回家试试。哈哈

多谢啦~

在不同的function里面return是不一样的。 我前面的写的太急,没有写好可能会有些误解(写回和返回不一样,注意socket的关闭)。不过你仔细按照那个思路理解下。

现在好像带 return 功能了呢

在这个例子中,res.json() 方法会结束 HTTP 响应,并发送 JSON 数据给客户端。一旦 res.json() 被调用,Express.js 会自动结束响应过程,并且不会再执行后续的代码。

如果你注释掉密码验证的部分,你会发现 res.json({"status":1}) 只有在用户存在且密码匹配的情况下才会被执行。如果用户不存在或密码错误,相应的错误信息会被发送并结束响应。

你可以通过使用回调函数或者 return 来确保在发送响应后不执行后续代码。下面是修改后的代码示例:

User.get(username, function(err, user) {
    if (err) {
        return res.status(500).json({ status: -1, msg: "Internal Server Error" });
    }

    if (!user) {
        console.log("Error");
        return res.json({ status: -1, msg: "Username Not exists" });
    }

    if (user.password !== password) {
        return res.json({ status: -1, msg: "Password Error" });
    }

    res.json({ status: 1 });
});

这样可以确保在每个条件分支中,一旦发送了响应,就不会再执行后续的代码。

回到顶部