1

我正在使用 Node.js + Express + nodejs-sqlite3 制作一个表单,提交时将在 slite3 数据库中插入一个新行。在查询成功时,我想写一些回复。

所以小问题只是:在 sqlite3.run() 的回调函数中修改将存储要显示的 html 的字符串

我读到了闭包,并通过方法传递一个对象来修改它自己的属性。但它似乎不起作用。它将传递对象的属性和方法,但回调函数结束时不会保留任何更改。我读到对象将作为参考传递,而不是副本。

这是代码:

app.post("/insert.html", function(req, res){
    function TheBody(){
        this.html = "";
        this.msg = "";
        this.num = "";
    }
    TheBody.prototype.add = function(string){
        this.html = this.html + string;
    }
    var body = new TheBody();

    body.msg = req.body.message;
    body.num = req.body.number;

    var insertCallback = function(data){
        return function(err){
            if( err != null){
                console.log("Can't insert new msg: " + err.message);
                data.add("ERROR-DB");                                               
            } else {
                console.log("Ok. Inserted: " + data.msg);
                console.log(data.html);
                data.add("OK - MSG: "+data.msg+" NUM: "+data.num);
                console.log(data.html);
            }
        };
    };                                                                                   

    var db = new lite.Database('database.db');
    var query = "INSERT INTO outbox (message, number) VALUES (?, ?)";
    db.run(query, [body.msg, body.num], insertCallback(body) );

    res.setHeader('Content-Type', 'text/html');
    res.setHeader('Content-Length', body.html.length);
    res.end(body.html);
}

在服务器端,我会看到

Ok. Inserted: TestString
[Blank space since data.html still has no information]
OK - MSG: TestString NUM: TestNumber [Showing that indeed was modified inside the function]

但是在客户端res.end(body.html);会发送一个空字符串。该对象未作为参考传递。

代码中缺少什么,以及我必须更改回调匿名函数中的字符串变量有哪些更简单的替代方法?

我已经知道如果它更简单,我可以response.write()直接在函数上编写。但是我发现只有在回调内部使用它才会起作用response.end(),否则(现在在外部)它将满足竞争条件,即缓冲区将在sqlite3.run()能够使用之前关闭response.write()

-------- 已答复 --------

正如 Justin Bicknell 所暗示并由 George P 确认的那样。Nodejs-sqlite3 函数是异步运行的。所以我在调用回调之前结束了到客户端的流,因此没有打印任何内容。这是一个更多关于“这是 SPART-nodejs,所以根据事件编写你的东西”的问题,而不是逻辑问题。我发现这种编程有点复杂,但除了我之外没有人告诉我使用 nodejs。对于那些想知道如何对数据库的查询顺序进行排序的人,nodejs-sqlite3 函数返回一个用于链接下一个查询的数据库对象。

由于我在每个处理的事件中只向客户端打印一次信息,因此生成的对象以如下方式结束:

function TheBody(response){
    this.response = response;
}
TheBody.prototype.printAll = function(string){
    this.response.setHeader('Content-Type', 'text/html');
    this.response.setHeader('Content-Length', string.length);
    this.response.end(string);
} 

宁愿将所有代码弄乱很多 res.setHeader() 行。

4

1 回答 1

2

默认情况下,node-sqlite3 方法是并行(异步)运行的。这意味着您的代码正在经历这个时间线:

  1. 您的代码调用db.run(...)
  2. 您的代码调用res.end(...)
  3. db.run完成并调用您的回调。

这是关于 SO 的大量问题的来源,因此您几乎可以肯定找到比我在合理时间内在这里写的任何内容更好的答案。

我将从这里开始:异步 Javascript 执行是如何发生的?什么时候不使用return语句?

于 2013-01-21T21:53:40.110 回答