为什么回应来自承诺`.then`方法反模式

时间:2016-02-26 20:13:24

标签: javascript angularjs angular-promise anti-patterns

我在StackOverflow上看到了人们建议为AngularJS服务提供回调函数的答案。

app.controller('tokenCtrl', function($scope, tokenService) {
    tokenService.getTokens(function callbackFn(tokens) {
        $scope.tokens = tokens;
    });
});

app.factory('tokenService', function($http) {
    var getTokens = function(callbackFn) {
        $http.get('/api/tokens').then (function onFulfilled(response) {
            callbackFn(response.data);
        });
    };

    return {
        getTokens: getTokens
    };
});

在我看来,这是一种反模式。 $http服务返回promise并且.then方法执行回调函数感觉就像是一个不健康的控制反转。

一个重新分解这样的代码如何解释为什么原始方式不是一个好主意?

2 个答案:

答案 0 :(得分:7)

您应该将其更改为

var getTokens = function() {
      return $http.get('/api/tokens');
    };

然后,在其他模块中使用

yourModule.getTokens()
  .then(function(response) {
    // handle it
  });

至于为什么它是反模式,我要说,首先,它不允许你进一步链接你的成功/失败处理程序方法。其次,它处理从调用者模块到被调用模块的响应处理的控制(这里可能不是非常重要,但它仍然施加相同的控制反转)。最后,你向你的代码库添加了promises的概念,对于一些团队成员来说可能不那么容易理解,但是然后使用promises作为回调,所以这真的没有意义。

答案 1 :(得分:1)

代码可以重新计算如下:

app.controller('tokenCtrl', function($scope, tokenService) {
    tokenService.getTokens.then ( callbackFn(tokens) {
        $scope.tokens = tokens;
    });
});

app.factory('tokenService', function($http) {
    var getTokens = function() {
        //return promise
        return $http.get('/api/tokens').then (function onFulfilled(response) {
                //return tokens
                return response.data;
            }
        );
    };

    return {
        getTokens: getTokens
    };
});

通过让服务返回承诺,并使用承诺的.then方法,可以实现相同的功能,具有以下优点:

  • 承诺可以保存并用于链接

  • 可以保存并使用承诺,以避免重复相同的$http电话。

  • 保留错误信息,可以使用.catch方法检索错误信息。

  • 承诺可以转发给其他客户。