2013-08-02 4 views
13

Ich habe und expressjs Anwendung und auf einer bestimmten Route rufe ich eine Funktion, die mit einem Benutzer aus der Datenbank durch den Aufruf res.json mit dem Datenbankdokument als Parameter reagiert. Ich verwende Versprechen basierte Bibliotheken und ich wollte den Callback inline, wo ich das Datenbankdokument in die Antwort einfügen. Aber das Programm schlägt fehl, wenn ich das tue. Kann jemand erklären warum? Ich frage mich auch, warum inlined Anrufe zu console.log tatsächlich funktionieren. Gibt es einen grundlegenden Unterschied zwischen den beiden Methoden res.json und console.log?Warum kann ich nicht direkt zu res.json anrufen?

Hier ist ein Beispiel dafür, was funktioniert und was nicht funktioniert. Angenommen, getUserFromDatabase() gibt ein Versprechen eines Benutzerdokuments zurück.

//This works 
var getUser = function(req, res) { 
    getUserFromDatabase().then(function(doc) { 
     res.json(doc); 
    });  
} 

//This does not work (the server never responds to the request) 
var getUserInline = function(req, res) { 
    getUserFromDatabase().then(res.json);  
} 

//This works (the object is printed to the console) 
var printUser = function(req, res) { 
    getUserFromDatabase().then(console.log);  
} 
+0

Es sieht aus wie eine Bindung Problem. http://alistapart.com/article/getoutbindingsituations – randunel

Antwort

12

Die json Funktion verliert seine korrekte this verbindlich, wenn sie so verwendet, da .then geht es ohne Referenz auf das Objekt res Eltern direkt aufzurufen, so binden sie:

var getUserInline = function(req, res) { 
    getUserFromDatabase().then(res.json.bind(res));  
} 
+0

Könnte dies als ein Fehler in der Bibliothek betrachtet werden oder gibt es keinen Weg um es beim Entwerfen des res-Objekts? –

+0

So funktioniert JavaScript. Die 'res.json'-Funktion könnte von der Bibliothek für Sie vorbelegt werden, aber das wäre in Javascript sehr unkonventionell. CoffeeScript ermöglicht objektorientierte Methoden vorbindend mit dem Fettpfeil ("=>") Operator, FYI. –

+0

@LudwigMagnusson 'res.json' ist keine Funktion, sondern eine Methode - das heißt, es ist abhängig von' this'. Während es in dieser Situation lästig sein kann, ist es viel besser als Funktionen, die ihren Kontext mit ihnen tragen müssen, weil es statisch zugewiesen werden kann. Die 'Antwort'-Klasse könnte ihre Methoden automatisch binden, aber das ist ein enormer Leistungsverlust, wenn' res.json' normal als Methode aufgerufen werden kann (meistens kann es). – Esailija