【问题标题】:javascript - wrong sequence of compilingjavascript - 错误的编译顺序
【发布时间】:2014-01-10 10:11:29
【问题描述】:

我想检查一个用户是否已经在我的数据库中(sqlite3)。

  • 如果用户存在:返回 500(错误!!)
  • 如果用户不存在:返回200(ok)

这就是我的脚本:服务器端的 node.js+express。

app.post('/adduser', function(req,res){
    db.serialize(function(){
        var user = req.body.user;
        var password = req.body.password;
        var err = false;

        db.each("SELECT name FROM users", function(err, row) {
            if (user == row.name) {
                console.log(row.name);
                err = true;
                console.log("a: " +err);
                res.send(500);
                return false;
            }
        });

        if (err==false) {
            console.log("b: " +err);
            res.send(200);
        }

    })
});

无论我是否提交现有用户名,我总是得到成功代码 200。这是来自服务器的日志:

b: false
testuser
a: true

我输入了一个现有用户,但它得到了代码 200。奇怪的是,我在 a 之前得到了 b

【问题讨论】:

  • Javascript 没有被编译它被运行,它没有被转换成任何东西,所以“编译”这个词是不正确的。
  • 如果用户存在,为什么会返回 500(内部服务器错误)。
  • err 是数据库错误,而不是找不到记录。改为修改您的第一个 if
  • 我想通知我的客户,该用户已经在我的数据库中并且无法添加。因此我使用 500 代码

标签: javascript jquery node.js express sqlite


【解决方案1】:

您的数据库查询是异步调用的。即使您指定 db.serialize,这将导致 sqlite 按照您指定的顺序运行其 sql-queries,DB 查询也会分离。

这意味着收到结果时会调用来自数据库的响应(您在“db.each ...”中的匿名回调函数)。

但是,程序会进一步运行,首先调用您的“if (err==false) ...”。

例如:

    var err = false; // called first

    db.each("SELECT name FROM users", function(err, row) {
       // called 3rd (after result from DB/disk)
    });

    if (err==false) {
       // called second
    }

db.each() 函数还接受第三个参数(请参阅API Documentation),在所有查询完成后调用。据此,您的代码应如下所示:

app.post('/adduser', function(req,res){
  db.serialize(function(){
    var user = req.body.user;
    var password = req.body.password;
    var err = false;

    db.each("SELECT name FROM users", function(err, row) {
        if (user == row.name) {
            console.log(row.name);
            err = true;
            console.log("a: " +err);
            res.send(500);
            return false;
        }
    }, function() {
        if (err==false) {
            console.log("b: " +err);
            res.send(200);
        }
    });
  })
});

在编码 node.js 时,您应该始终牢记任何 disk/io/net/db/etc.被称为异步,回调中的代码将在以下代码之后执行。

【讨论】:

  • 感谢您的回答。如果我有足够的声誉,我会投票赞成你的答案
【解决方案2】:

“each”函数将与结果集中的每一行异步回调。您可以添加一个完成处理程序作为最终参数,一旦所有行都返回,该处理程序将被调用。

db.each("SELECT name FROM users", function(dberr, row) {
    if (user == row.name) {
        console.log(row.name);
        err = true;
        console.log("a: " +err);
        res.send(500);
         return false;
    }
}, function() { // Completion Handler
    if (err==false) {
        console.log("b: " +err);
        res.send(200);
    }
});

注意:我还修改了您的第一个回调函数的第一个参数,以免范围混淆。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    • 2014-01-09
    • 1970-01-01
    相关资源
    最近更新 更多