AngularJS。如何在服务中解析承诺后更新指令?

时间:2015-01-23 18:24:55

标签: angularjs asynchronous promise

这是对我previous question的跟进。

我有一个需要一些时间的AJAX请求。假设我得到两部分数据,var1和var2。我只想在与

绑定到主控制器范围的指令中使用var1
var1: '=',

我从服务中得到了var1和var2,但由于它们有不同的用途,我不能简单地使用我从$ http调用获得的一个承诺。

我试图实现它,但它仍然没有像我想象的那样工作。该服务具有以下形式:

myModule.service('MyService', ['$http', '$q', function($http, $q) {
    var var1 = $q.defer();
    var var2 = $q.defer();
    httpPromise = $http({
        url: "/myService",
        method: "GET",
        params: {}
    }).success(function(data, status) {
        var1.resolve(data.var1);
        var2.resolve(data.var2);
    })

    return {
        getVar1: function() {
            return var1.promise;
        },
        getVar2: function() {
            return var2.promise;
        },
    }
}]);

在控制器中,我按如下方式分配承诺:

$scope.var1 = MyService.getVar1();
$scope.var2 = MyService.getVar2();

但是,一旦在服务中解决了promise,该指令似乎不知道var1的值已更改。我认为这将由AngularJS引擎处理。

在我看来,这里唯一的方法是进行大量的then()调用,这会引入更多的混乱而不是好的。我想我会留下来(我想是一个丑陋的黑客......)

$scope.$watch('var1', ...)

在指令内,除非有人向我展示了更好的方向。

1 个答案:

答案 0 :(得分:3)

在我看来,您只需要进行一次then()来电,使用then()是使用承诺的正确方法:

指令内部:

var1.then(function (value) {
    // use the resolved value
});

关于承诺的一些附注:

这是多余的:

return {
    getVar1: function() {
        return var1.promise;
    },
    getVar2: function() {
        return var2.promise;
    },
}

你可以这样做:

return {
    var1Promise: var1.promise,
    var2Promise: var2.promise,
};

然后像这样访问它们:

$scope.var1 = MyService.var1Promise;

获得完全相同的结果。


你也成了deferred antipattern的牺牲品,它实际上已经在你的代码中引入了错误(如果$http调用失败,你将无法捕获错误。)

您可以在没有延迟的情况下实现服务,使用更少的代码行,最重要的是 能够捕获错误,如下所示:

myModule.service('MyService', ['$http', '$q', function($http, $q) {
    var httpPromise = $http({
        url: "/myService",
        method: "GET",
        params: {}
    });

    return {
        var1Promise: httpPromise.then(function (response) {
            return response.data.var1;
        }),
        var2Promise: httpPromise.then(function (response) {
            return response.data.var2;
        }),
    };
}]);

我同意你的看法,所有这些.then()电话都不是世界上最美丽的景象。当对箭头功能的广泛支持到达时,我会很高兴。