2017-02-28 3 views
0

Ist forEach in einem Array async? Süßigkeiten ist eine Reihe von Süßigkeiten Objekte.Ist Array.forEach in Node.js asynchron?

app.get('/api/:id',function(req, res){ 

    console.log("Get candy"); 
    var id = req.params.id; 

    candies.forEach(function(candy, index){ 
    if(candy.id == id){ 
     console.log("Candy found. Before return"); 
     return res.json(candy); 
     console.log("Candy found. After return"); 
    } 
    }); 

    console.log("Print error message"); 
    return res.json({error: "Candy not found"}); 
}); 

in der Konsole bekomme ich

[nodemon] starting `node app.js` 
listning on port 3000 
Get candy 
Candy found. Before return 
Print error message 
Error: Can't set headers after they are sent. 
    at ServerResponse.setHeader (_http_outgoing.js:367:11) 
    .... 

Ist das eine kürzliche Änderung? Es ist eine Weile her, seit ich getan habe node.js

+3

Warum haben Sie Code nach einem 'return'? – Thilo

+0

Wenn es async wäre, hätten Sie zuerst die Fehlermeldung "Print error message". Warum wäre es asynchron? Auch Thilo hat richtig darauf hingewiesen - was ist der Sinn von Code nach 'return' Anweisung? Das wird nie ausgeführt werden. – Mjh

+1

Auch die "Rückkehr" in der inneren Funktion wird nur die innere Funktion verlassen, nicht die äußere. – Thilo

Antwort

1

Sie erhalten die Ausnahme Can't set headers after they are sent., weil Sie versuchen, eine Antwort zweimal zurückgeben - (möglicherweise) einmal in candies.forEach und noch einmal in der letzten Zeile der Route. Beachten Sie auch, dass Code nach einer return sowieso nicht ausgeführt wird.

Hier ist, wie Sie es umschreiben, den Fehler zu vermeiden -

app.get('/api/:id',function(req, res){ 

    console.log("Get candy"); 
    var id = req.params.id; 
    var foundCandy = false; 
    candies.forEach(function(candy, index){ 
     if(candy.id == id){ 
      foundCandy = true; 
      console.log("Candy found. Before return"); 
     } 
    }); 

    if (foundCandy) { 
     return res.json(candy); 
    } else { 
     return res.json({error: "Candy not found"}); 
    } 
}); 
+0

@Jens Verwenden von 'Array.filter' wie @Vladu Ionuts Antwort [hier] (http://Stackoverflow.com/a/42504948/398713) führt auch zu saubereren und präziseren Code. – GPX

+0

Danke! Ich weiß, wie ich es lösen kann. Ich bin nur neugierig, warum ich dieses Verhalten bekomme. Beide res.json (Süßigkeiten) und res.json ({Fehler: "Candy nicht gefunden"}); rufen wir an. Das scheint mir nicht logisch, es sei denn forEach ist jetzt eine asynchrone Funktion. – Jens

+0

Got it ... Siehe @Thilo antworten – Jens

1

Sie können Array.filter verwenden, um die Süßigkeiten zu finden.

app.get('/api/:id', function(req, res) { 

    console.log("Get candy"); 
    var id = req.params.id; 

    var result = candies.filter(candy => candy.id == id); 

    if (result.length) { 
    return res.json(result[0]); 
    } else { 
    console.log("Print error message"); 
    return res.json({ 
     error: "Candy not found" 
    }); 
    } 
}); 
+0

An alle anderen, die diese Frage betrachten: Die "Rückkehr res.json (Süßigkeiten);" Wird nur von der inneren Funktion zurückgegeben, die im forEach-Argument definiert wurde, und nicht von der gesamten Funktion zurückgegeben wird. Dort werden beide Antworten aufgerufen. – Jens

Verwandte Themen