私のコード:
let AuthUser = data => {
return google.login(data.username, data.password).then(token => { return token } )
}
そして私がこのような何かを実行しようとすると:
let userToken = AuthUser(data)
console.log(userToken)
私は手に入れました:
Promise { <pending> }
しかし、なぜ?
私の主な目標は、約束を返すgoogle.login(data.username, data.password)
からトークンを変数に入れることです。そしてその後にのみ、いくつかのアクションを実行します。
その結果がまだ解決されていない限り、約束は常に保留中のログを記録します。約束の状態(解決済みまたは未定)に関係なく、結果を取得するには、約束に対して.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"
})
何故ですか?
約束は順方向のみです。あなたはそれらを一度だけ解決することができます。 Promise
の解決された値は、その.then
または.catch
メソッドに渡されます。
Promises/A +の仕様によると:
プロミス解決手順は、入力としてプロミスと値を取る抽象操作で、これを[[Resolve]](プロミス、x)と表します。 xが可算ならば、xは少なくともいくらか約束のように振る舞うという仮定の下で、約束にxの状態を採用させることを試みます。そうでなければ、それは値xで約束を満たす。
このテーブルの処理により、Promise/A +準拠のthenメソッドが公開されている限り、promise実装は相互運用できます。また、Promises/A +の実装では、妥当なthenメソッドを使って非準拠の実装を「同化」することもできます。
この仕様はパースするのが少し難しいので、それを分解しましょう。規則は以下のとおりです。
.then
ハンドラ内の関数が値を返す場合、Promise
はその値で解決されます。ハンドラが別のPromise
を返した場合、元のPromise
は連鎖したPromise
の解決された値で解決されます。次の.then
ハンドラーは常に、前の.then
で返された連鎖約束の解決された値を含みます。
それが実際にどのように機能するかは、以下でより詳細に説明されます。
1。 .then
関数の戻り値は、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。 .then
関数が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"
});
私はこの質問が2年前に尋ねられたことを知っています、しかし私は同じ問題にぶつかりました、そして、問題に対する答えはES6以来です、あなたは単に関数戻り値のようにawait
をすることができます:
let AuthUser = function(data) {
return google.login(data.username, data.password).then(token => { return token } )
}
let userToken = await AuthUser(data)
console.log(userToken) // your data
then
メソッドは、保留中のpromiseを返します。これは、then
の呼び出しで登録された結果ハンドラの戻り値によって非同期に解決されるか、呼び出されたハンドラ内でエラーをスローすることによって拒否されます。
そのため、AuthUser
を呼び出しても突然ユーザーを同期的にログインさせることはありませんが、ログインが成功した(または失敗した)後に登録されたハンドラーが呼び出されるという約束を返します。私は全てのログイン処理をlogin promiseのthen
節で起動することを提案します。例えば。名前付き関数を使用してフローの順序を強調する
let AuthUser = data => { // just the login promise
return google.login(data.username, data.password);
};
AuthUser(data).then( processLogin).catch(loginFail);
function processLogin( token) {
// do logged in stuff:
// enable, initiate, or do things after login
}
function loginFail( err) {
console.log("login failed: " + err);
}
PromiseのMDNセクションを参照してください。 特に、 then()の戻り型に注目してください。
ログインするには、ユーザーエージェントはサーバーにリクエストを送信し、レスポンスを受信するのを待つ必要があります。ラウンドトリップ中にアプリケーションが完全に実行を停止すると、通常はユーザーエクスペリエンスが悪くなります。ログインする(または他の形式のサーバーとのやり取りを行う)JS機能では、Promiseなどが使用されます非同期に結果を配信するため。
さて、return
ステートメントは常にそれらが現れる関数の文脈で評価されることにも注意してください。
let AuthUser = data => {
return google
.login(data.username, data.password)
.then( token => {
return token;
});
};
ステートメントreturn token;
は、then()
に渡される無名関数がトークンを返すべきであることを意味しました。AuthUser
関数が返すべきではないことを意味します。 AuthUser
が返すのは、google.login(username, password).then(callback);
を呼び出した結果です。
最終的にあなたのコールバックtoken => { return token; }
は何もしません。代わりに、then()
への入力は実際に何らかの方法でトークンを処理する関数である必要があります。