Я предполагаю, что с помощью bluebirds promisify вы бы обещали bcrypt.compare так (вам НЕ ОБЯЗАТЕЛЬНО использовать асинхронную часть имени)
let compareAsync = Promise.promisify(bcrypt.compare);
потому что userObject
в первом .then нужно использовать во втором .then, вы не можете просто связать .then, возвращая compareAsync, потому что тогда следующий .then не будет иметь доступа к userObject
одно исправление - использовать переменную, которая будет в области действия обоих .then (но тьфу)
username = username.toUpperCase();
let text = "SELECT * FROM users WHERE username = $1";
let values = [username];
let uo; //hacky the outer scoped variable
database.one(text, values).then(function (userObject) {
uo = userObject;
return compareAsync(password, userObject.password);
}).then(function(same) {
if (!same) {
throw new Error("Password mismatched!");
}
const serializeObject = {_id: uo._id};
return next(null, serializeObject);
}).catch(function (err) {
return next(err, null);
});
другой (на мой взгляд, более чистый) вариант - это вложенный .then
username = username.toUpperCase();
let text = "SELECT * FROM users WHERE username = $1";
let values = [username];
database.one(text, values).then(function (userObject) {
return compareAsync(password, userObject.password)
// [optional] following three lines to generate a "nicer" error for compare failure
.catch(function(err) {
throw "bcrypt.compare failed";
})
// nested .then to pass on the userObject and same at the same time
.then(function (same) {
return { same: same, userObject: userObject };
});
}).then(function (result) {
let same = result.same,
userObject = result.userObject;
if (!same) {
throw new Error("Password mismatched!");
}
let serializeObject = { _id: userObject._id };
return next(null, serializeObject);
}).catch(function (err) {
return next(err, null);
});
ПРИМЕЧАНИЕ: у bluebird есть функция promisifyAll... которая обещает функции в объекте и добавляет (по умолчанию) постфикс Async
к имени функции - я думаю, вы можете выбрать другое имя постфикса, но документация расскажет вам больше
при обещании одной функции вы сами объявляете имя - вышеприведенное могло быть легко
let trumpIsBigly = Promise.promisify(bcrypt.compare);
тогда вы просто использовали бы trumpIsBigly
, где код имеет compareAsync
Последняя возможность
Свернутый вручную обещанный compareAsync (снятый в основном из ответа vitaly-t, но с дополнениями)
function compareAsync(password1, password2, inValue) {
return new Promise(function (resolve, reject) {
bcrypt.compare(password1, password2, function (err, same) {
err = err || (!same && new Error("Password mismatched!"));
if (err) {
reject(err);
} else {
resolve(inValue);
}
});
});
}
Теперь compareAsync будет разрешать входящее значение inValue
только в том случае, если нет ошибки, И то же верно.
username = username.toUpperCase();
let text = "SELECT * FROM users WHERE username = $1";
let values = [username];
database.one(text, values).then(function (userObject) {
return compareAsync(password, userObject.password, userObject)
}).then(function (userObject) {
let serializeObject = { _id: userObject._id };
return next(null, serializeObject);
}).catch(function (err) {
return next(err, null);
});
Что делает «цепочку» очень простой!
person
Jaromanda X
schedule
01.02.2017
bcrypt.compare
для вас - person Jaromanda X   schedule 01.02.2017I am not sure if it possible to turn this code to promise base
любой код можно превратить в промисы, иpromisify
решение для вашегоbcrypt
модуля — самое простое. - person vitaly-t   schedule 01.02.2017