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

新手上路,请多包涵

我的代码:

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) 获取令牌到变量中。然后才执行一些操作。

原文由 Src 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 3.7k
2 个回答

只要其结果尚未解决,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"
 })

这是为什么?

承诺只是向前的方向;您只能解决它们一次。 Promise 的解析值被传递给它的 .then.catch 方法。

细节

根据 Promises/A+ 规范:

承诺解决过程是一个抽象操作

输入一个承诺和一个值,我们将其表示为 [[Resolve]](promise,

X)。如果 x 是 thenable,它会尝试让 Promise 采用

x,假设 x 的行为至少有点像

承诺。否则,它以值 x 履行承诺。

对 thenables 的这种处理允许 Promise 实现

互操作,只要它们公开一个符合 Promises/A+ 的然后

方法。它还允许 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 ,那么该链式 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"
 });

原文由 Bamieh 发布,翻译遵循 CC BY-SA 4.0 许可协议

我知道这个问题是 2 年前提出的,但我遇到了同样的问题,问题的答案是自 ES2017 以来,您可以简单地 await 函数返回值(截至目前,仅适用于 async 函数),如:

 let AuthUser = function(data) {
  return google.login(data.username, data.password)
}

let userToken = await AuthUser(data)
console.log(userToken) // your data

原文由 Marius Seack 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏