如何使用$ q和$ http调用编写服务而不重复

时间:2013-09-17 21:56:05

标签: javascript angularjs angularjs-service

我正试图找出一种优雅的方式来编写AngularJS服务,而不必使用$ q语法重复。

目前,我正在编写如下服务:

(function() {

    function ServiceFactory($q, $timeout, $http) {
        return {
            getFoo: function() {
                var deferred = $q.defer();

                $timeout(function() {
                    $http.get('/the/foo/thing').then(function(response) {
                        if (response.isError) {
                            deferred.reject();
                        } else {
                            deferred.resolve(response.data.foo);
                        }
                    }, function() {
                        deferred.reject();
                    });
                });

                return deferred.promise;
            }
        };
    }

    angular.module('myapp').service('MyService', ['$q', '$timeout', '$http', ServiceFactory]);

}.call(this));

它运作良好,买我总是写下一堆代码只是为了延迟$ http.get并暴露一个Promise。有时我会在成功回调中有一些额外的东西,比如处理数据,创建一个不同的响应对象......但大多数时候,就像上面的代码一样:call $q.defer + $http.get().then... + return promise

所以,我正在考虑一种清理/减少代码的方法,而不会影响我正在做的事情的清晰度,例如,如果另一个开发人员打开文件,它应该不是一个谜。

作为旁注,这里的$ http服务实际上是一个装饰器,处理服务器响应以给我一个更结构化的对象,包括response.isErrorresponse.data

另外,我在另一个问题{1}中看到了类似的解决方案,但这并不相同。只返回$http.get().then()的响应将在响应时向控制器公开整个响应,这不是预期的效果。相反,当我拨打MyService.getFoo().then(...)时,我希望foo对象作为服务响应,由服务器通过response.data.foo提供,或者呼叫errorCallback

我忘了提及:我的服务器不是RESTful,所以$resource现在不是一个选项。我的网址更像/thing/get/:id/thing/do-stuff/:id

{1} Similar question

1 个答案:

答案 0 :(得分:0)

经过一段时间的思考,我想出了一种更好的方式来编写服务。我对$http响应做了一些更改,现在我的实现只要Controller调用http.get()或任何http方法就返回一个Promise。通过这种实现,在大多数情况下,我已经将每个请求的方法代码减少到两行或三行。现在我应该尝试使用AngularJS装饰器设置。

这里有一个工作示例:

http://embed.plnkr.co/p4EHQAbE40XWXjBWqjIM/preview