1. ホーム
  2. javascript

[解決済み】非同期関数が値の代わりにPromise { <pending> }を返すのはなぜですか?

2022-04-15 08:43:46

質問

私のコード

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]] (promise.) と表記する。 x). xがthenableの場合、promiseにその状態を採用させようとする。 xは少なくともいくらかは同じように振る舞うという仮定のもとに プロミス そうでなければ,promiseを値xで満たす.

このようにthenableを扱うことで、プロミスの実装は Promises/A+に準拠したthenを公開する限り、相互運用が可能です。 メソッドを使用します。また、Promises/A+の実装が「同化」することを可能にします。 合理的なthenメソッドを持つ不適合な実装を行う。

この仕様は少し解析が難しいので、分解して説明しましょう。ルールは

の中の関数が .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 関数が返す 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"
  });