Обіцянка завжди буде зафіксованою до тих пір, поки її результати ще не вирішені. Потрібно закликати .then
обіцяти зафіксувати результати незалежно від стану обіцянки (вирішено чи ще не очікується):
let AuthUser = function(data) {
return google.login(data.username, data.password).then(token => { return token } )
}
let userToken = AuthUser(data)
console.log(userToken) // Promise { <pending> }
userToken.then(function(result) {
console.log(result) // "Some User token"
})
Чому так?
Обіцянки мають лише напрямок вперед; Вирішити їх можна лише один раз. Розв’язане значення a Promise
передається його .then
або .catch
методам.
Деталі
Відповідно до специфікацій Обіцянки / A +:
Процедура розв’язування обіцянки - це абстрактна операція, яка приймає як вхід обіцянку та значення, які ми позначаємо як [[Розв’язати]] (Обіцянка, х). Якщо x є підданим, він намагається змусити обіцянку прийняти стан x, при припущенні, що x поводиться принаймні дещо як обіцянка. В іншому випадку він виконує обіцянку зі значенням x.
Таке поводження з thenables дозволяє взаємодії з обіцянками взаємодіяти, якщо вони виявляють метод Promis / A +-compliant, а потім. Це також дозволяє реалізаціям Promises / A + "засвоювати" невідповідні реалізації з розумними методами.
Цю специфікацію трохи важко розібрати, тому давайте її розбимо. Правило таке:
Якщо функція .then
обробника повертає значення, то Promise
розв'язується з цим значенням. Якщо обробник повертає інший Promise
, то оригінал Promise
вирішується з розділеним значенням ланцюжка Promise
. Наступний .then
обробник завжди буде містити вирішене значення ланцюгової обіцянки, повернене в попередньому .then
.
Як саме це працює, описано нижче більш докладно:
1. Повернення .then
функції буде вирішеним значенням обіцянки.
function initPromise() {
return new Promise(function(res, rej) {
res("initResolve");
})
}
initPromise()
.then(function(result) {
console.log(result); // "initResolve"
return "normalReturn";
})
.then(function(result) {
console.log(result); // "normalReturn"
});
2. Якщо .then
функція повертає a Promise
, то розв'язане значення цієї ланцюгової обіцянки передається наступному .then
.
function initPromise() {
return new Promise(function(res, rej) {
res("initResolve");
})
}
initPromise()
.then(function(result) {
console.log(result); // "initResolve"
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("secondPromise");
}, 1000)
})
})
.then(function(result) {
console.log(result); // "secondPromise"
});