承诺待定

Src*_*Src 89 javascript node.js promise

我的代码:

let AuthUser = data => {
  return google.login(data.username, data.password).then(token => { return token } )
}
Run Code Online (Sandbox Code Playgroud)

当我尝试运行这样的东西时:

let userToken = AuthUser(data)
console.log(userToken)
Run Code Online (Sandbox Code Playgroud)

我越来越:

Promise { <pending> }
Run Code Online (Sandbox Code Playgroud)

但为什么?

我的主要目标是将令牌从中google.login(data.username, data.password)返回一个promise,转换为变量.然后才会执行某些操作.

Bam*_*ieh 121

只要其结果尚未解决,承诺将始终记录暂挂.无论承诺状态(已解决或仍未决定),您必须调用.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"
})
Run Code Online (Sandbox Code Playgroud)

这是为什么?

承诺只是前进的方向; 您只能解决一次.a的Promise已解析值将传递给其.then.catch方法.

细节

根据Promises/A +规范:

promise解析过程是一个抽象操作,它将promise和value作为输入,我们将其表示为[[Resolve]](promise,x).如果x是一个可能的,它会尝试使x采用x的状态,假设x的行为至少有点像promise.否则,它满足x值的承诺.

对thenables的这种处理允许promise实现进行互操作,只要它们公开符合Promises/A +的方法即可.它还允许Promises/A +实现使用合理的方法"同化"不一致的实现.

这个规范有点难以解析,所以让我们分解它.规则是:

如果.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"
  });
Run Code Online (Sandbox Code Playgroud)

2.如果.then函数返回a 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"
  });
Run Code Online (Sandbox Code Playgroud)

  • 我将其添加为书签,以便我可以**永远保留它。** 我花了很长时间来寻找真正清晰且可读的规则,以了解如何实际构建承诺。你对 Promises/A+ 规范的块引用是一个完美的例子,说明了为什么它是自学承诺的 PITA。这也是我唯一一次看到 setTimeout 在没有混淆课程本身的情况下使用。以及很好的参考,谢谢。 (3认同)
  • 将结果分配给另一个变量时它不起作用。 (3认同)
  • 它仍然返回 Promise { &lt;Pending&gt; } (2认同)

小智 10

我知道这个问题是在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
Run Code Online (Sandbox Code Playgroud)

  • 您不需要`.then(token =&gt; return token)`,那只是不必要的传递。只需返回google登录电话即可。 (3认同)
  • 它给了我这个错误 ``` let answer = wait getAnswer(url); ^^^^^ 语法错误:await 仅在异步函数和模块的顶层主体中有效``` (3认同)
  • 对于 ES8 / Nodejs,如果您在异步函数之外使用“await”,则会引发错误。也许这里更好的例子是将 `AuthUser` 函数设置为 `async`,然后以 `return wait google.login(...);` 结尾 (2认同)

Has*_*can 6

如果这种情况发生在像数组这样的多个值上。

[ 
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> }
]
Run Code Online (Sandbox Code Playgroud)

您可以使用Promise.all()它来解决所有承诺。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all


tra*_*r53 5

then方法返回一个挂起的承诺,它可以通过调用中注册的结果处理程序的返回值异步解析then,或者通过在调用的处理程序中抛出错误来拒绝。

因此,调用AuthUser不会突然同步登录用户,而是返回一个承诺,在登录成功(或失败)后将调用其当时注册的处理程序。我建议通过then登录承诺的子句触发所有登录处理。EG 使用命名函数突出显示流程顺序:

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);
}
Run Code Online (Sandbox Code Playgroud)