2015-06-05 13 views
5

Wenn ich die Wasserlinie ORM verwende, wenn ich die Bluebird-Versprechen-API, die standardmäßig geliefert wird, verbrauchen möchte, wie ich die Verarbeitung zurück an den Controller übergebe.SailsJS Waterline mit Bluebird Promises

Unten ist der Code:

module.exports = { 
    //Authenticate 
    auth: function (req, res) { 
     user = req.allParams(); 
     //Authenticate 
     User.authenticate(user, function (response) { 
      console.log(response); 
      if (response == true) { 
       res.send('Authenticated'); 
      } else { 
       res.send('Failed'); 
      } 
     }); 
    } 
}; 


module.exports = { 
    // Attributes 

    // Authenticate a user 
    authenticate: function (req, cb) { 
     User.findOne({ 
      username: req.username 
     }) 
     .then(function (user) { 
      var bcrypt = require('bcrypt'); 
      // check for the password 
      bcrypt.compare(req.password, user.password, function (err, res) { 
       console.log(res); 
       if (res == true) { 
        cb(true); 
       } else { 
        cb(false); 
       } 
      }); 
     }) 
     .catch(function (e) { 
      console.log(e); 
     }); 
    } 
}; 

bin ich einfach versucht, eine Authentifizierungsfunktion zu implementieren. Die Geschäftslogik ist einfach. Was mich verwirrt, ist, wie der Anfragefluss an den Controller seither übergeben wird. Das Versprechen reagiert nicht, wenn ich versuche, eine Antwort zurückzugeben, aber ein cb (Wert) funktioniert.

+0

Wo Sie zurücksenden Versprechen in diesem Code? – vanadium23

+0

Laut dem Dokument (http://sailsjs.org/#!/documentation/reference/waterline/queries), hat Waterline eine partielle Implementierung von Bluebird, ich habe meinen Kopf um den Code nach dem User.find gewickelt. ..then –

Antwort

7

Der Schlüssel zur Arbeit mit Versprechen ist, niemals die Kette zu durchbrechen. Eine Versprechenskette hängt von jedem Schritt ein Versprechen oder einen Wert oder einen Fehler zurückgeben.

Der folgende Code ist neu geschrieben. Beachten Sie, dass

  • Jeder Rückruf auf dem Weg, das Versprechen Kette etwas und jede Funktion gibt kehrt sie mit arbeitet (auch .auth(), es irgendwann nützlich sein könnte)
  • I Bluebird verwendet habe .promisifyAll()bcrypt Spiel zu machen entlang
  • Ich habe .authenticate() von Ihrer Anfrage/Antwort-Infrastruktur entkoppelt, indem Sie die username und password Argumente explizit machen. Auf diese Weise kann es einfacher wiederverwendet werden.

So, jetzt haben wir (nicht zu 100% getestet, ich nicht die Installation von Wasserlinie gestört hat):

module.exports = { 
    // authenticate the login request 
    auth: function (req, res) { 
     var params = req.allParams(); 
     return User.authenticate(params.username, params.password) 
     .then(function() { 
      res.send('Authenticated'); 
     }) 
     .fail(function (reason) { 
      res.send('Failed (' + reason + ')'); 
     }); 
    } 
}; 

und

var Promise = require("bluebird"); 
var bcrypt = Promise.promisifyAll(require('bcrypt')); 

module.exports = { 
    // check a username/password combination 
    authenticate: function (username, password) { 
     return User.findOne({ 
      username: username 
     }) 
     .then(function (user) { 
      return bcrypt.compareAsync(password, user.password) 
     }) 
     .catch(function (err) { 
      // catch any exception problem up to this point 
      console.log("Serious problem during authentication", err); 
      return false; 
     }) 
     .then(function (result) { 
      // turn `false` into an actual error and 
      // send a less revealing error message to the client 
      if (result === true) { 
       return true; 
      } else { 
       throw new Error("username or password do not match"); 
      } 
     }); 
    } 
}; 
+2

dies löscht eine Menge Fragen, die ich über Versprechungen hatte. +1 –

+2

Sie brauchen etwas gewöhnungsbedürftig, aber danach sind sie ein schönes Werkzeug. Besser im Vergleich zur nativen Callback-Architektur des Knotens. – Tomalak

+0

Sollte dies nicht auch ein Versprechen anstelle von wahr/falsch zurückgeben? Ich nehme an, sonst gibt es keinen tatsächlichen Rückruf, den Sie in einem Controller tun könnten, oder irgendwo auf der http-Ebene, das wäre dann ein Synchronisierungsanruf. – mkbrv