创建调用promise的方法或快速完成操作

时间:2015-02-12 04:52:56

标签: javascript promise ecmascript-6

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

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

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

我可以立即看到的问题是!令牌路径可能需要一段时间,因此我的登录方法应该返回一个承诺。问题是如何处理其他路径?

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

3 个答案:

答案 0 :(得分:2)

正如@Esailija已经提到过,如果你的函数是异步的(在这种情况下返回promise),它必须总是返回promise。在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的回调内部抛出的任何错误都将拒绝承诺。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

您忘记返回第一个承诺,因此您的方法与消费者同步。如果您的方法是异步的,则必须从所有代码路径返回promise,包括抛出一个:

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);
  }
}

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

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;
    }
  })
}