在下面的代码中,我有一个名为queryString
的select查询,它检索有关已存储在数据库中的一些推文的信息。我想检索这些推文中提到的主题标签,以便向用户显示推文信息及其主题标签:
var queryString = 'select Tweet.Label, Tweet.TDate, Tweet.TLink, Author.Lable, Author.ALink from Tweet, Author where Tweet.AuthorID IN (select ID from Author where Lable = ?) AND Author.ID IN (select ID from Author where Lable = ?)';
var query = connection.query(queryString, [term,term], function(err, rows) {
console.log(rows);
//res.write(JSON.stringify(rows));
var tweet = JSON.parse(JSON.stringify(rows));
for(var i in tweet){
res.write("Author: ");
res.write("<a href='" + tweet[i].ALink + "' target='_blank'>" + tweet[i].Lable + "</a> <br/>");
res.write("Date: " + tweet[i].TDate + "<br/>");
res.write("Tweet: " + "<a href='" + tweet[i].TLink + "' target='_blank'>" + tweet[i].Label + "</a> <br/>");
var query1 = connection.query('select Label from Hashtag where ID IN (select HashID from tweethashs where TweetID IN (select ID from Tweet where Label = ?))', [tweet[i].Label], function(err, rows1) {
var tweet1 = JSON.parse(JSON.stringify(rows1));
for(var i in tweet1){
res.write("Hashtag: ");
res.write(tweet1[i].Label);
}
}
);
res.write("<br/><br/>");
}
res.end();
});
我所做的是我在推文循环中包含了对主题标签的查询,以便我将推文作为hashtags查询的参数(在where子句中)。当我运行代码时,我收到以下错误:
events.js:154
throw er; // Unhandled 'error' event
^
Error: write after end
at ServerResponse.OutgoingMessage.write (_http_outgoing.js:426:15)
at Query._callback (C:\Users\Nasser\Desktop\Spring Semester\Intelligent Web\
Node JS\SocialSearch.js:58:11)
at Query.Sequence.end (C:\Users\Nasser\Desktop\Spring Semester\Intelligent W
eb\Node JS\node_modules\mysql\lib\protocol\sequences\Sequence.js:96:24)
at Query._handleFinalResultPacket (C:\Users\Nasser\Desktop\Spring Semester\I
ntelligent Web\Node JS\node_modules\mysql\lib\protocol\sequences\Query.js:144:8)
at Query.EofPacket (C:\Users\Nasser\Desktop\Spring Semester\Intelligent Web\
Node JS\node_modules\mysql\lib\protocol\sequences\Query.js:128:8)
at Protocol._parsePacket (C:\Users\Nasser\Desktop\Spring Semester\Intelligen
t Web\Node JS\node_modules\mysql\lib\protocol\Protocol.js:280:23)
at Parser.write (C:\Users\Nasser\Desktop\Spring Semester\Intelligent Web\Nod
e JS\node_modules\mysql\lib\protocol\Parser.js:73:12)
at Protocol.write (C:\Users\Nasser\Desktop\Spring Semester\Intelligent Web\N
ode JS\node_modules\mysql\lib\protocol\Protocol.js:39:16)
at Socket.<anonymous> (C:\Users\Nasser\Desktop\Spring Semester\Intelligent W
eb\Node JS\node_modules\mysql\lib\Connection.js:96:28)
at emitOne (events.js:90:13)
有人可以帮我解决这个问题
答案 0 :(得分:1)
基本上你在for循环中做了几个异步数据库查询,但是当同步for循环结束时你关闭了你的响应。所以当db查询结束时你试着写一个已经关闭的响应。
<div class="header with-bord">
<h3 class="title">New Message <a (click)="closeEmail()" class="close"><i class="fa fa-times"></i></a></h3>
</div>
我添加了两个计数器,它将跟踪您请求的数据库查询和已回复的查询。当这两个计数器相等时,所有数据库事务和响应写入都已完成,因此您可以关闭响应流。
虽然这不是最佳做法。您应该检查async模块或尝试在数据库查询中使用promises。
修改强> 我更改了代码,以便在内部查询完成时发生写入。现在要小心,因为写入的顺序不会遵循第一个查询的顺序,但它会根据内部查询首先结束的内容进行写入。我必须告诉你,这不是实现这一目标的最佳方式,你需要阅读异步模块和我之前告诉你的承诺。另请参阅如何在javascript中混合异步和同步操作!
答案 1 :(得分:0)
如果您选择通过停止res.end()来执行此操作,则您不确定您的响应是否将按照与数组中的推文相同的顺序编写。
for循环是同步的,但查询是异步的,这意味着它们可以比之前开始的更快完成。这在理论上会导致写入随机发生。
您可以使用的是async.map。
基本上,您可以使用以下代码来代替foreach循环:
注意:为了更好地理解这一点,请先阅读async.map代码。
//the tweet for which I get the information from DB
var getTweetInfo = function(tweet, callback){
con.query(query, function(err, tweetInformation){
if(err) {
console.log(err);
//with this you are passing the error back into the async.map function. Otherwise it would be lost (Bad javascript :P)
callback("Error getting tweets" + err);
}
else{
//in here you can make any changes to the tweet information before sending it as a response
//this will send the tweetInformation into the results array
callback(null, tweetInformation);
}
});
}
//tweetsArray is the array with tweets
//getTweeetInfo is a function that will get each tweet from the tweets array and will apply the query to it
async.map(tweetsArray, getTweetInfo, function(error, tweetInformationArray){
if (error) {
console.log(error);
}else{
//'results' will hold an array with the information for each tweet in the same order as the initial tweets
res.json({
response: tweetInformationArray
});
}
})
在此之后,您可以解析前端的响应。数据是由异步组成的(你没有让事件循环等待),这意味着你可以通过它并在屏幕上很好地显示它。