2015-06-05 2 views
5

При использовании Waterline ORM, если я хочу использовать обещание bluebird api, которое отправлено по умолчанию, как передать обработку обратно контроллеру.SailingJS Waterline with Bluebird Promises

Ниже приведен код:

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

Я просто пытаюсь реализовать функцию аутентификации. Бизнес-логика прямолинейна. Я смущен, так как поток запросов передается контроллеру с тех пор. Обещание не отвечает, если я пытаюсь вернуть ответ, но выполнение cb (value) работает.

+0

Где вы возвращения Promise в этом коде? – vanadium23

+0

Согласно документу (http://sailsjs.org/#!/documentation/reference/waterline/queries), ватерлиния имеет частичную реализацию Bluebird, я обволакиваю его вокруг кода после User.find .. .. then –

ответ

7

Ключом к работе с обещаниями является никогда не разрушать цепь. Цепочка обещания зависит от каждого шага либо , возвращая обещание, либо значение, или throwing.

Ниже приведена переписка с кодом. Обратите внимание, что

  • Каждый обратного вызова в пути возвращает что-то и каждая функция возвращает цепочку обещание он работает с (даже .auth(), это может быть полезно в какой-то момент)
  • Я использовал BlueBird-х .promisifyAll() сделать bcrypt игру
  • Я отделил .authenticate() от вашей инфраструктуры запроса/ответа, сделав аргументы username и password явным. Таким образом, его можно использовать повторно.

Так что теперь мы (не 100% тестирование, я не потрудился установка ватерлинии):

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

и

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

это очищает много вопросов, которые у меня были о обещаниях. +1 –

+2

Они привыкли, но после этого они прекрасный инструмент. Лучше во всех отношениях, по сравнению с традиционной архитектурой обратного вызова узла. – Tomalak

+0

Должно ли это не возвращать обещание вместо истинного/ложного? Я полагаю, что в противном случае нет никакого обратного вызова, который вы могли бы сделать в контроллере или где-то на уровне http, чтобы это было тогда вызовом синхронизации. – mkbrv

Смежные вопросы