我的代码:

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.password),返回一个承诺,到一个变量。然后再执行一些动作。


当前回答

请参阅MDN承诺部分。特别是,查看then()的返回类型。

要登录,用户代理必须向服务器提交请求并等待接收响应。由于在请求往返期间让应用程序完全停止执行通常会导致糟糕的用户体验,实际上每个让您登录(或执行任何其他形式的服务器交互)的JS函数都将使用Promise或非常类似的东西来异步交付结果。

现在,还要注意,return语句总是在它们出现的函数的上下文中求值。所以当你写:

let AuthUser = data => {
  return google
    .login(data.username, data.password)
    .then( token => {
      return token;
    });
};

语句返回令牌;意味着传递给then()的匿名函数应该返回令牌,而不是AuthUser函数应该返回令牌。AuthUser返回的是调用谷歌的结果。login(用户名,密码).then(回调);,这恰好是一个承诺。

最终你的回调令牌=>{返回令牌;}什么都不做;相反,then()的输入需要是一个以某种方式实际处理标记的函数。

其他回答

你的承诺还在等待,完成它

userToken.then(function(result){
console.log(result)
})

在你剩下的代码之后。 所有这些代码所做的是.then()完成你的承诺,并在结果变量中捕获最终结果,并在控制台打印结果。 请记住,不能将结果存储在全局变量中。 希望这个解释能帮到你。

请参阅MDN承诺部分。特别是,查看then()的返回类型。

要登录,用户代理必须向服务器提交请求并等待接收响应。由于在请求往返期间让应用程序完全停止执行通常会导致糟糕的用户体验,实际上每个让您登录(或执行任何其他形式的服务器交互)的JS函数都将使用Promise或非常类似的东西来异步交付结果。

现在,还要注意,return语句总是在它们出现的函数的上下文中求值。所以当你写:

let AuthUser = data => {
  return google
    .login(data.username, data.password)
    .then( token => {
      return token;
    });
};

语句返回令牌;意味着传递给then()的匿名函数应该返回令牌,而不是AuthUser函数应该返回令牌。AuthUser返回的是调用谷歌的结果。login(用户名,密码).then(回调);,这恰好是一个承诺。

最终你的回调令牌=>{返回令牌;}什么都不做;相反,then()的输入需要是一个以某种方式实际处理标记的函数。

我之前也遇到过同样的问题,但我在前端的情况有点不同。我还是会分享我的场景,也许有人会觉得有用。

我有一个api调用/api/user/注册在前端的电子邮件,密码和用户名作为请求体。在提交表单(注册表单)时,会调用一个handler函数,它会启动对/api/user/register的取回调用。我在这个处理函数的开始行中使用了event.preventDefault(),所有其他行,比如形成请求体以及获取调用都是在event.preventDefault()之后编写的。这将返回一个待处理的承诺。

但是当我把请求正文的形成代码放在event.preventDefault()上面时,它返回了真正的承诺。是这样的:

event.preventDefault();
    const data = {
        'email': email,
        'password': password
    }
    fetch(...)
     ...

而不是:

     const data = {
            'email': email,
            'password': password
        }
     event.preventDefault();
     fetch(...)
     ...

试试这个

var number1 = document.getElementById("number1"); var number2 = document.getElementById("number2"); startAsync.addEventListener("click", function() { if (number1.value > 0 && number2.value > 0) { asyncTest(parseInt(number1.value), parseInt(number2.value)).then(function(result) { document.getElementById("promiseResolved").textContent = "promiseResolved: " + result }); } else { asyncTest(1, 2).then(function(result) { document.getElementById("promiseResolved").textContent = "promiseResolved: " + result }); } }); async function asyncTest(a, b) { return await (a + b); }; <button id="startAsync">start Async function</button><br /> <input type="number" id="number1" /><br /> <input type="number" id="number2" /><br /> <span id="promiseResolved"></span><br />

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

因此,调用AuthUser不会突然同步地让用户登录,而是返回一个承诺,在登录成功(或失败)后调用该承诺的注册处理程序。我建议通过登录承诺的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);
}