La promesa siempre se registrará como pendiente siempre que sus resultados aún no se hayan resuelto. Debe recurrir .then
a la promesa para capturar los resultados independientemente del estado de la promesa (resuelto o aún pendiente):
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"
})
¿Porqué es eso?
Las promesas son solo una dirección hacia adelante; Solo puede resolverlos una vez. El valor resuelto de a Promise
se pasa a sus métodos .then
o .catch
.
Detalles
De acuerdo con la especificación Promises / A +:
El procedimiento de resolución de promesas es una operación abstracta que toma como entrada una promesa y un valor, que denotamos como [[Resolver]] (promesa, x). Si x es un thenable, intenta hacer que la promesa adopte el estado de x, bajo el supuesto de que x se comporta al menos de alguna manera como una promesa. De lo contrario, cumple la promesa con el valor x.
Este tratamiento de las posibilidades permite que las implementaciones de las promesas interoperen, siempre que expongan un método que cumpla con las promesas / A +. También permite que las implementaciones de Promises / A + "asimilen" las implementaciones no conformes con métodos razonables.
Esta especificación es un poco difícil de analizar, así que analicémosla. La regla es:
Si la función en el .then
controlador devuelve un valor, entonces se Promise
resuelve con ese valor. Si el manejador devuelve otro Promise
, entonces el original se Promise
resuelve con el valor resuelto del encadenado Promise
. El siguiente .then
controlador siempre contendrá el valor resuelto de la promesa encadenada devuelta en el anterior .then
.
La forma en que realmente funciona se describe a continuación con más detalle:
1. La devolución de la .then
función será el valor resuelto de la promesa.
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. Si la .then
función devuelve un Promise
, entonces el valor resuelto de esa promesa encadenada se pasa a lo siguiente .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"
});