在Javascript上的匿名函数回调中修改对象属性的正确方法
我正在使用Node.js+Express+nodejs-sqlite3制作一个表单,提交时将在slite3数据库中插入新行。 在查询成功时,我想写下一定的回答 因此,一个大的小问题是:在sqlite3.run()的回调函数中修改一个字符串,该字符串将存储要显示的html 我读过关于闭包的书,并用方法传递一个对象来修改它自己的属性。但它似乎不起作用。它将传递对象属性和方法,但在回调函数结束时不会保留任何更改。我了解到对象将作为引用而不是副本传递 代码如下:在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
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(…)
db.run
完成并调用回调我想从这里开始:db.run方法是异步的吗?@JustinBicknell似乎是这样。读我刚才加的最后一段。我无法使用response.write(),因为这显然是一种异步行为。