2016-04-07 10 views
0

Was bedeutet, dass in Bezug auf die folgenden Code bedeutet auch, arbeitet die res.send aber fein in meiner Konsole bekomme ich die folgende Meldung:Kann Header nicht senden, nachdem bereits gesendet?

http.js:689 
throw new Error('Can\'t set headers after they are sent.'); 

app.get('/summoner/:summonerName', function(req, res) { 
lolapi.Summoner.getByName(req.params.summonerName, function(err, obj) { 
    var options = { 
    beginIndex: 0, 
    endIndex: 1 
    }; 
    lolapi.MatchList.getBySummonerId(obj['savisaar2'].id, options, function(err, matches) { 
    var gameMatches = matches.matches; 
    for(var i = 0; i < gameMatches.length; i++) { 
     lolapi.Match.get(gameMatches[i].matchId, function(err, games) { 
     res.send({profile : obj, matchHistory : games}); 
     }); 
    } 
    }); 
}); 
}); 
+0

Mögliche Duplikat [Node.js Fehler: nicht Header gesetzt, nachdem sie gesendet werden] (http://stackoverflow.com/questions/7042340/node -js-error-cant-set-headers-after-the-are-sended) – JordanHendrix

+0

Sie können nur 'res .send() 'einmal pro Anfrage. Sie rufen es mehrmals in einer Schleife auf. – jfriend00

+0

Was ist die Absicht dieses Codes? Sie rufen 'lolapi.Match.get()' innerhalb einer 'for'-Schleife auf und versuchen dann 'res.send()' für jede 'lolapi.Match.get()' zu tun. Der Aufruf von res.send() 'mehr als einmal für eine bestimmte Anfrage verursacht den angezeigten Fehler. Aber wie soll der Code funktionieren? Was sollen Sie mit all Ihren Ergebnissen machen? Versuchen Sie, alle Ergebnisse zusammen zu sammeln und dann alle als Antwort zu senden? – jfriend00

Antwort

0

Wie ich in meinen Kommentaren erläutert, werden Sie res.send() innen ein rufender for Schleife, was bedeutet, dass Sie es mehr als einmal aufrufen. Sie können es nur einmal pro Anfrage anrufen. Aus diesem Grund sehen Sie die Fehlermeldung in der Konsole.

Es ist nicht klar, genau das, was Ihr Code wirklich tun will, aber wenn der Wunsch, alle Ergebnisse in ein Array zu sammeln und sie alle als Antwort senden, dann können Sie das wie folgt tun:

app.get('/summoner/:summonerName', function (req, res) { 
    lolapi.Summoner.getByName(req.params.summonerName, function (err, obj) { 
     if (err) { 
      return res.status(500).end(); 
     } 
     var options = {beginIndex: 0, endIndex: 1}; 
     lolapi.MatchList.getBySummonerId(obj['savisaar2'].id, options, function (err, matches) { 
      var gameMatches = matches.matches; 
      var results = []; 
      for (var i = 0; i < gameMatches.length; i++) { 
       lolapi.Match.get(gameMatches[i].matchId, function (err, games) { 
        if (err) { 
         return res.status(500).end(); 
        } 
        results.push({profile: obj, matchHistory: games}); 
        // if all results are done, then send response 
        if (results.length === gameMatches.length) { 
         res.json(results); 
        } 
       }); 
      } 
     }); 
    }); 
}); 

Hinweis: Ich habe auch rudimentäre Fehlerbehandlung hinzugefügt.

Wenn Sie die Ergebnisse in der bestimmten Reihenfolge möchten, dass Sie dann angefordert, dann können Sie ein wenig mehr Code hinzufügen, dass, wie dies zu tun:

app.get('/summoner/:summonerName', function (req, res) { 
    lolapi.Summoner.getByName(req.params.summonerName, function (err, obj) { 
     if (err) { 
      return res.status(500).end(); 
     } 
     var options = {beginIndex: 0, endIndex: 1}; 
     lolapi.MatchList.getBySummonerId(obj['savisaar2'].id, options, function (err, matches) { 
      var gameMatches = matches.matches; 
      var results = new Array(gameMatches.length); 
      var cntr = 0; 
      for (var i = 0; i < gameMatches.length; i++) { 
       (function(index) { 
        lolapi.Match.get(gameMatches[i].matchId, function (err, games) { 
         if (err) { 
          return res.status(500).end(); 
         } 
         ++cntr; 
         results[index] = {profile: obj, matchHistory: games}; 
         // if all results are done, then send response 
         if (cntr === gameMatches.length) { 
          res.json(results); 
         } 
        }); 
       })(i); 
      } 
     }); 
    }); 
}); 

Da Promises im Jahr 2016 heute Standard sind, hier eine Idee was diese wie mit der Drossel Versprechen Bibliothek aussehen könnte:

const Promise = require('bluebird'); 
Promise.promisifyAll(lolapi.Summoner); 
Promise.promisifyAll(lolapi.MatchList); 
Promise.promisifyAll(lolapi.Match); 

app.get('/summoner/:summonerName', function (req, res) { 
    var main; 
    lolapi.Summoner.getByNameAsync(req.params.summonerName).then(function(obj) { 
     main = obj; 
     var options = {beginIndex: 0, endIndex: 1}; 
     return lolapi.MatchList.getBySummonerIdAsync(obj['savisaar2'].id, options); 
    }).then(function(matches) { 
     var gameMatches = matches.matches; 
     return Promise.map(gameMatches, function(item){ 
      return lolapi.Match.getAsync(item.matchId).then(function(games) { 
       return {profile: main, matchHistory: games}; 
      }); 
     }); 
    }).then(function(results) { 
     res.json(results); 
    }).catch(function(err) { 
     res.status(500).end(); 
    }); 
} 
Verwandte Themen