小编典典

为什么我的异步函数返回 Promise {} 而不是一个值?

all

我的代码:

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)返回承诺的令牌放入变量中。然后才执行一些操作。


阅读 63

收藏
2022-06-18

共1个答案

小编典典

只要其结果尚未解决,promise 将始终记录未决。.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被传递给它的.thenor.catch方法。

细节

根据 Promises/A+ 规范:

承诺解决过程是一个抽象操作,将承诺和值作为输入,我们将其表示为 [Resolve]。如果 x 是
thenable,它会尝试让 Promise 采用 x 的状态,假设 x 的行为至少有点像 Promise。否则,它以值 x 履行承诺。

对 thenables 的这种处理允许 Promise 实现互操作,只要它们公开一个符合 Promises/A+ 的 then 方法。它还允许
Promises/A+ 实现使用合理的 then 方法“同化”不符合要求的实现。

这个规范有点难解析,所以让我们分解一下。规则是:

如果.then处理程序中的函数返回一个值,则Promise使用该值解析。如果处理程序返回另一个Promise,那么原始Promise的将使用链接的已解析值解析Promise。下一个.then处理程序将始终包含前面返回的链式承诺的解析值.then

下面更详细地描述了它的实际工作方式:

1..then函数的返回值将是promise的resolved值。

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,则该链式 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"
  });
2022-06-18