Can only make one GET request without error: "Can't set headers after they are sent."
Can only make one GET request without error: "Can't set headers after they are sent."
我希望我的 http 服务器 return 一些 json return 从异步函数中编辑。我设法让它工作,但它只工作一次,然后它抛出:"Can't set headers after they are sent." 错误。
下面是代码:
var server = restify.createServer();
server.get('/', function(req, res, next) {
feed("dilma",[]);
eventEmitter.on('retorno', function(retorno){
res.send(retorno);
});
});
server.on("listening", function() {
console.log("server running!");
});
server.listen(7171);
提要功能:
var feed = function headLinesBySite(word, l) {
if (!Array.isArray(l)) {
console.log("por favor passe um array");
return false;
}
if (l !== []) {
links = l;
}
links = ["http://www.estadao.com.br/", "http://atarde.uol.com.br/"];
var teste = 0;
var final = [];
for (i = links.length - 1; i >= 0; i--) {
findHeadlines(links[i], word.toLowerCase(), function(r, url) {
final.push({
url: url,
manchetes: r
});
//console.log(url+" - "+r);
teste++;
console.log((teste / links.length) * 100 + "%");
if (teste === links.length) {
console.log("Concluído!");
console.log(final);
eventEmitter.emit('retorno', final);
}
});
}
};
查找标题函数:
var findHeadlines = function findHeadlines(url, word, cb) {
request(url, {
timeout: 1000
}, function(error, response, body) {
if (!error && response.statusCode == 200) {
$ = cheerio.load(body);
texto = [];
var retorno = [];
b = $('body').text().toLowerCase();
c = b.replace(/\s+/g, ' ');
texto = c.split("¬");
for (var i = texto.length - 1; i >= 0; i--) {
if (texto[i].search(word) !== -1 && texto[i].length < 100) {
//console.log(texto[i]);
retorno.push("+" + texto[i] + "+");
}
}
cb(retorno, url);
} else {
console.log(error);
cb([], url);
}
});
};
我第一次调用 localhost/7171 时得到了信息,但在那之后,任何 GET 请求都会抛出:"Can't set headers after they are sent."。我读过一些关于这个相同错误的类似问题,但其中 none 帮助我修复了它...我只想让 GET 请求等待 feed 函数的异步 return...感谢任何帮助。
有
eventEmitter.on('retorno', function(retorno){
res.send(retorno);
});
您正在订阅 retorno
活动,但您从未取消订阅。因此,如果第二次引发该事件,旧的路由处理程序将再次运行 res.send
- 但现在在一个已经关闭的连接上。
将 on
更改为 once
,问题 可能 就会消失。有关更多详细信息,您必须仔细查看您的整个代码。
希望对您有所帮助。
关于订阅和取消订阅,我的意思是订阅就像说 "From now on, I want to get notified when event X happens"。这一直有效,直到您说您不再感兴趣(即您退订)。 on
相当于subscribe
,通常要用removeListener
到unsubscribe
。
如果您使用 once
,您实际上是在说您正在订阅,但仅限于事件发生一次 - 然后您希望自动取消订阅。这就是它起作用的原因:-)
我希望我的 http 服务器 return 一些 json return 从异步函数中编辑。我设法让它工作,但它只工作一次,然后它抛出:"Can't set headers after they are sent." 错误。
下面是代码:
var server = restify.createServer();
server.get('/', function(req, res, next) {
feed("dilma",[]);
eventEmitter.on('retorno', function(retorno){
res.send(retorno);
});
});
server.on("listening", function() {
console.log("server running!");
});
server.listen(7171);
提要功能:
var feed = function headLinesBySite(word, l) {
if (!Array.isArray(l)) {
console.log("por favor passe um array");
return false;
}
if (l !== []) {
links = l;
}
links = ["http://www.estadao.com.br/", "http://atarde.uol.com.br/"];
var teste = 0;
var final = [];
for (i = links.length - 1; i >= 0; i--) {
findHeadlines(links[i], word.toLowerCase(), function(r, url) {
final.push({
url: url,
manchetes: r
});
//console.log(url+" - "+r);
teste++;
console.log((teste / links.length) * 100 + "%");
if (teste === links.length) {
console.log("Concluído!");
console.log(final);
eventEmitter.emit('retorno', final);
}
});
}
};
查找标题函数:
var findHeadlines = function findHeadlines(url, word, cb) {
request(url, {
timeout: 1000
}, function(error, response, body) {
if (!error && response.statusCode == 200) {
$ = cheerio.load(body);
texto = [];
var retorno = [];
b = $('body').text().toLowerCase();
c = b.replace(/\s+/g, ' ');
texto = c.split("¬");
for (var i = texto.length - 1; i >= 0; i--) {
if (texto[i].search(word) !== -1 && texto[i].length < 100) {
//console.log(texto[i]);
retorno.push("+" + texto[i] + "+");
}
}
cb(retorno, url);
} else {
console.log(error);
cb([], url);
}
});
};
我第一次调用 localhost/7171 时得到了信息,但在那之后,任何 GET 请求都会抛出:"Can't set headers after they are sent."。我读过一些关于这个相同错误的类似问题,但其中 none 帮助我修复了它...我只想让 GET 请求等待 feed 函数的异步 return...感谢任何帮助。
有
eventEmitter.on('retorno', function(retorno){
res.send(retorno);
});
您正在订阅 retorno
活动,但您从未取消订阅。因此,如果第二次引发该事件,旧的路由处理程序将再次运行 res.send
- 但现在在一个已经关闭的连接上。
将 on
更改为 once
,问题 可能 就会消失。有关更多详细信息,您必须仔细查看您的整个代码。
希望对您有所帮助。
关于订阅和取消订阅,我的意思是订阅就像说 "From now on, I want to get notified when event X happens"。这一直有效,直到您说您不再感兴趣(即您退订)。 on
相当于subscribe
,通常要用removeListener
到unsubscribe
。
如果您使用 once
,您实际上是在说您正在订阅,但仅限于事件发生一次 - 然后您希望自动取消订阅。这就是它起作用的原因:-)