【问题标题】:Creating a method that calls a promise OR completes an action quickly创建一个调用promise的方法或快速完成一个动作
【发布时间】:2015-02-12 04:52:56
【问题描述】:

我正在创建一个采用以下形式的方法:

login() {
  var token = this.cookieManager.getCookie("token");

  if(!token)  
  {
     client.post(url, data).then(response => {
        this.accessToken = response.content;
     });
  } 
  else 
  {
    this.accessToken = token;
  }
}

我可以立即看到的问题是 !token 路径可能需要一段时间,因此我的登录方法实际上应该返回一个承诺。问题是 else 路径怎么办?

我可以创建并返回一个承诺,但这个承诺除了硬编码的“成功”之外没有任何实际的返回值。这看起来很奇怪,那么是否有另一种选择来处理这种情况?

【问题讨论】:

  • 你应该把它作为一个承诺 for accessToken - 这就是你的 login 函数基本上获得的。当您不知道它是否存在时,无需将其存储在属性中。

标签: javascript promise ecmascript-6


【解决方案1】:

正如@Esailija 已经提到的,如果您的函数是异步的(在这种情况下返回承诺),它必须始终返回承诺。在 ES7 中,async 关键字正是为此目的而存在的。但在 ES7 之前,您可以保证这种行为只需使用 Promise.resolve().then(() => {}) 构造包装您的代码:

login() {
  return Promise.resolve().then(() => {
    var token = this.cookieManager.getCookie("token");

    if (token) {
      return this.accessToken = token;
    }

    return client.post(url, data).then(response => {
      return this.accessToken = response.content;
    });
  });
}

现在login 方法也返回accessToken,我认为它更清晰。任何将在传递给then 的回调中抛出的错误都将拒绝该承诺。

【讨论】:

  • 实际上您的代码不起作用,因为它缺少else。你不想总是返回client.post(…)
【解决方案2】:

else 路径可以只返回一个已经解决的承诺。所以两条路径都会返回一个承诺。在一种情况下,它已经解决,在另一种情况下,它将在异步操作完成时解决。在这两种情况下,调用者都只是在 promise 上使用.then()

【讨论】:

    【解决方案3】:

    您忘记返回第一个承诺,因此您的方法对消费者来说似乎是同步的。如果你的方法是异步的,你必须从所有代码路径中返回 Promise,包括 throwing 路径:

    login() {
      try {
        var token = this.cookieManager.getCookie("token");
    
        if(!token)  
        {
          return client.post(url, data).then(response => {
            this.accessToken = response.content;
          });
        } 
        else 
        {
          this.accessToken = token;
        }
        return Promise.resolve();
      } catch (e) {
        return Promise.reject(e);
      }
    }
    

    大多数 Promise 库都包含一个帮助程序,使这变得非常简单:

    login() {
      return Promise.try(_ => {
        var token = this.cookieManager.getCookie("token");
    
        if(!token)  
        {
          return client.post(url, data).then(response => {
            this.accessToken = response.content;
          });
        } 
        else 
        {
          this.accessToken = token;
        }
      })
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      • 2013-05-14
      • 2021-12-24
      • 2020-11-21
      • 2018-06-12
      • 2015-07-10
      • 2016-02-23
      相关资源
      最近更新 更多