【问题标题】:Can only make one GET request without error: "Can't set headers after they are sent."只能发出一个 GET 请求而不会出错:“发送后无法设置标头。”
【发布时间】:2016-08-31 18:31:06
【问题描述】:

我希望我的 http 服务器返回一些从异步函数返回的 json。我设法让它工作,但它只工作一次,然后它抛出:“发送后无法设置标题。”错误。

下面是代码:

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 请求都会抛出:“发送后无法设置标头。”。我已经阅读了一些关于这个相同错误的类似问题,但没有一个帮助我修复它......我只想让 GET 请求等待 feed 函数的异步返回......感谢任何帮助。

【问题讨论】:

    标签: javascript node.js express asynchronous restify


    【解决方案1】:

    eventEmitter.on('retorno', function(retorno){   
        res.send(retorno);
    });
    

    您正在订阅retorno 事件,但您从未取消订阅。因此,如果该事件再次引发,旧的路由处理程序会再次运行 res.send - 但现在是在一个已经关闭的连接上。

    on 更改为once,问题可能就消失了。有关更多详细信息,您必须仔细查看您的整个代码。

    希望这会有所帮助。

    关于订阅和取消订阅,我的意思是订阅就像说“从现在开始,我想在事件 X 发生时得到通知”。这一直有效,直到您说您不再感兴趣(即您取消订阅)。 on 相当于subscribe,通常你必须使用removeListenerunsubscribe

    如果您使用once,您实际上是在说您正在订阅,但仅在事件发生一次之前 - 然后您想自动取消订阅。这就是它起作用的原因:-)

    【讨论】:

    • 编辑并添加了整个代码,我会尝试使用一次并发布结果!
    • 能否请您简单解释一下事件的订阅和退订? “曾经”奏效了!太感谢了!等待 10 分钟以绿色(接受)您的答案!
    • 我已经更新了我的答案,也许这会对你有所帮助:-)
    猜你喜欢
    • 2016-05-09
    • 2015-05-21
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 2021-03-15
    • 2018-08-11
    • 2021-02-17
    • 2011-04-21
    相关资源
    最近更新 更多