在Javascript上的匿名函数回调中修改对象属性的正确方法

在Javascript上的匿名函数回调中修改对象属性的正确方法,javascript,node.js,function,sqlite,anonymous,Javascript,Node.js,Function,Sqlite,Anonymous,我正在使用Node.js+Express+nodejs-sqlite3制作一个表单,提交时将在slite3数据库中插入新行。 在查询成功时,我想写下一定的回答 因此,一个大的小问题是:在sqlite3.run()的回调函数中修改一个字符串,该字符串将存储要显示的html 我读过关于闭包的书,并用方法传递一个对象来修改它自己的属性。但它似乎不起作用。它将传递对象属性和方法,但在回调函数结束时不会保留任何更改。我了解到对象将作为引用而不是副本传递 代码如下: app.post("/insert.ht

我正在使用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()行。

node-sqlite3方法在默认情况下是(异步的)。这意味着您的代码将经历以下时间线:

  • 您的代码调用db.run(…)
  • 您的代码调用res.end(…)
  • db.run
    完成并调用回调
  • 这是这里大量问题的来源,所以你几乎可以肯定地找到一个比我在合理时间内写的任何东西都更好的答案


    我想从这里开始:

    db.run方法是异步的吗?@JustinBicknell似乎是这样。读我刚才加的最后一段。我无法使用response.write(),因为这显然是一种异步行为。