2015-06-05 11 views
5

Quando si utilizza l'ORM della linea di galleggiamento, se si desidera utilizzare la promessa bluebird api è quella che viene spedita per impostazione predefinita come si passa l'elaborazione al controller.SailsJS linea di galleggiamento con Bluebird Promesse

Di seguito si riporta il codice:

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

Sto semplicemente cercando di implementare una funzione di autenticazione. La logica aziendale è semplice. Ciò di cui sono confuso è il modo in cui il flusso di richieste viene restituito al controller da allora. La promessa non risponde se provo a restituire una risposta, ma facendo un cb (valore) funziona.

+0

Dove stai tornando Promessa in questo codice? – vanadium23

+0

Secondo il documento (http://sailsjs.org/#!/documentation/reference/waterline/queries), la linea di galleggiamento ha una parziale implementazione di Bluebird, sto avendo la testa intorno al codice dopo l'User.find .. ... poi –

risposta

7

La chiave per lavorare con le promesse è non interrompere mai la catena. Una catena di promesse dipende da ogni passaggio restituendo una promessa o un valore oppure un errore.

Quanto segue è una riscrittura del codice. Si noti che

  • Ogni richiamata nel percorso restituisce qualcosa e ogni funzione restituisce la catena promessa che funziona con (anche .auth(), ma potrebbe essere utile a un certo punto)
  • ho usato BlueBird di .promisifyAll() fare bcrypt gioco lungo
  • Ho disaccoppiato .authenticate() dall'infrastruttura richiesta/risposta rendendo espliciti gli argomenti username e password. In questo modo può essere riutilizzato più facilmente.

Così ora abbiamo (non al 100% provato, non mi sono preoccupato di galleggiamento installazione):

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

e

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

questo chiarisce un sacco di domande che ho avuto sulle promesse. +1 –

+2

Ci si abitua, ma dopo sono un bellissimo strumento. Migliore in tutti i modi, rispetto all'architettura nativa di callback del nodo. – Tomalak

+0

Questo dovrebbe anche non restituire una promessa anziché vero/falso? Suppongo che altrimenti non ci sia una vera e propria callback che potresti fare in un Controller, o da qualche parte a livello http quindi questa sarebbe una chiamata di sincronizzazione. – mkbrv