The promise will always log pending as long as its results are not resolved yet. You must call .then
on the promise to capture the results regardless of the promise state (resolved or still pending):
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" })
Why is that?
Promises are forward direction only; You can only resolve them once. The resolved value of a Promise
is passed to its .then
or .catch
methods.
Details
According to the Promises/A+ spec:
The promise resolution procedure is an abstract operation taking as input a promise and a value, which we denote as [[Resolve]](promise, x). If x is a thenable, it attempts to make promise adopt the state of x, under the assumption that x behaves at least somewhat like a promise. Otherwise, it fulfills promise with the value x.
This treatment of thenables allows promise implementations to interoperate, as long as they expose a Promises/A+-compliant then method. It also allows Promises/A+ implementations to “assimilate” nonconformant implementations with reasonable then methods.
This spec is a little hard to parse, so let’s break it down. The rule is:
If the function in the .then
handler returns a value, then the Promise
resolves with that value. If the handler returns another Promise
, then the original Promise
resolves with the resolved value of the chained Promise
. The next .then
handler will always contain the resolved value of the chained promise returned in the preceding .then
.
The way it actually works is described below in more detail:
1. The return of the .then
function will be the resolved value of the promise.
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. If the .then
function returns a Promise
, then the resolved value of that chained promise is passed to the following .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" });