2016-05-05 9 views
2

Ich möchte, dass mein HTTP-Server einige von einer asynchronen Funktion zurückgegebene JSON zurückgibt. Ich habe es geschafft, es funktioniert, aber es funktioniert nur einmal, dann wirft es: "Kann Header nicht festlegen, nachdem sie gesendet werden." Error.Kann nur eine GET-Anfrage ohne Fehler machen: "Header können nach dem Senden nicht gesetzt werden."

hier ist der folgende Code:

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); 

Einspeisefunktion:

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); 
      } 
     }); 
    } 
}; 

findHeadlines Funktion:

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); 
     } 
    }); 
}; 

Das erste Mal, wenn ich localhost/7171 ich die Info bekommen rufen, Aber danach wirft jede GET-Anfrage: "Header können nach dem Senden nicht gesetzt werden.". Ich habe einige ähnliche Fragen über den gleichen Fehler gelesen, aber keiner von ihnen hat mir geholfen, es zu beheben ... Ich möchte nur die GET-Anfrage warten auf die asynchrone Rückkehr der Feed-Funktion ... Schätzen Sie jede Hilfe.

Antwort

2

Mit

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

Sie zum retorno Ereignis abonniert haben, aber man kann nie wieder abmelden. Wenn das Ereignis ein zweites Mal ausgelöst wird, führt der alte Routen-Handler daher erneut res.send aus - aber jetzt auf einer bereits geschlossenen Verbindung.

Ändern Sie on zu once und das Problem könnte weg sein. Für weitere Details müsste man sich den gesamten Code genauer ansehen.

Hoffe, das hilft.

Mit dem Abonnieren und Abmelden meine ich, dass Abonnieren ist wie "Ich möchte benachrichtigt werden, wenn Ereignis X passiert". Dies ist gültig, bis Sie sagen, dass Sie nicht mehr interessiert sind (d. H., Sie haben sich abgemeldet). on ist das Äquivalent von subscribe, normalerweise müssen Sie removeListener zu unsubscribe verwenden.

Wenn Sie once verwenden, sagen Sie effektiv, dass Sie abonnieren, aber nur bis das Ereignis ein einziges Mal passiert ist - und Sie möchten sich automatisch abmelden. Deshalb funktioniert es dann :-)

+0

bearbeitet und den ganzen Code hinzugefügt, ich werde versuchen, einmal zu verwenden und die Ergebnisse zu veröffentlichen! –

+1

Könnten Sie bitte eine kurze Erklärung zum An- und Abmelden von Veranstaltungen geben? Das "Einmal" hat funktioniert! Ich danke dir sehr! Warten Sie die 10 Minuten, bis Ihre Antwort grün ist! –

+1

Ich habe meine Antwort aktualisiert, vielleicht hilft dir das :-) –