Обіцянка завжди буде зафіксованою до тих пір, поки її результати ще не вирішені. Потрібно закликати .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"
});