在resolve函数内返回promise作为其延续。

7

背景

我正在使用Angular。我有一个名为UserService服务,用于处理登录、认证和用户数据请求。

get方法需要在进行get请求之前检查用户是否具有有效(未过期)的身份验证令牌。 如果是,则进行请求,如果不是,则请求一个令牌,然后进行请求。

问题

这个get方法需要隐藏其复杂的请求。它必须仅返回Promise,就像只进行了一个请求一样。

因此,以下是使用示例:

UserService
    .get()
    .then(data => { ... })
    .catch(error => { ... })

错误解决方案

检查令牌是否已过期。如果已过期,请返回请求以刷新令牌,在那里进行并返回GET请求。如果未过期,只需进行并返回GET请求。如下所示:

function get() {
    if (isTokenExpired(token))
        return $http
            .post(url + '/refreshtoken', 'token=' + refreshToken)
            .then(response => {
                token = response.data.token
                return $http.get(url + '?token=' + token)
            })
            .catch(response => { ... })
    else
        return $http.get(url + '?token=' + token)
}

但是它返回一个Promise,我需要像这样处理它:
UserService
    .get()
    .then(request => {
        request // THAT IS NOT GOOD
            .then(data => { ... })
            .catch(error => { ... })
    })
    .catch(error => { ... })

任何类似使用示例的内容!

正确的解决方案

如何在处理身份验证的服务上创建此get方法,并将其隐藏在将使用它的控制器中,使其与使用示例一样简单?


1
在您的Get响应中,如何知道您的令牌已过期? - Manu Obre
2
你真的尝试过这段代码吗?我无法相信then回调中的request是一个Promise。 - Bergi
2个回答

3

But it's returning a promise for a promise that I will have to handle like this:

 UserService.get().then(request => { request.then(data => { … }) })

编号。

承诺可以链接,任何“承诺对于承诺”的内容都会被隐式地转换为内部结果的承诺。你的“错误解决方案”代码就像原样工作。


0
这是一个例子。基本上,您需要使用额外的.then()进行转换。

angular.module('app', [])
  .service('UserService', function($http) {
    let url = 'https://jsonplaceholder.typicode.com';

    function getUserData(token) {
      return $http.get(url + '/users/1', {
          token: token
        })
        .then(resp => resp.data);
    }

    this.get = function(tokenIsValid) {
      if (!tokenIsValid){
        console.log('refreshing');
        return $http.post(url + '/posts', {
            refreshToken: 'rt'
          })
          .then(getUserData)
        }
      return getUserData();
    }
    return this;
  })
  .run(function($rootScope, UserService) {
    $rootScope.get = (valid) => {
      console.log('Getting with ' + (valid? '':'in') + 'valid token');
      UserService.get(valid)
        .then(console.log)
        .catch(console.error);
    }
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <button ng-click="get()">Get invalid</button>
  <button ng-click="get(true)">Get valid</button>
</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接