Angular:返回 $q.defer().promise 而不是 $http promise

Angular: Returning a $q.defer().promise instead of an $http promise

看了很多 Egghead.io 视频,我注意到一个常见的模式是 return 自定义承诺并在回调中解决它。

.factory('myFact', function($q, $http) {
    return {
        getData: function() {
            var deferred = $q.defer();
            $http.get('/path/to/api')
                .success(function(data) {
                    deferred.resolve(data);
                });
            return deferred.promise;
        }
    };
});

我通常会这样写:

.factory('myFact', function($http) {
    return {
        getData: function() {
            return $http.get('/path/to/api')
                .then(function(res) {
                    return res.data;
                });
        }
    };
});

return$q.defer() 承诺比 $http 承诺有任何优势吗?这些方法看起来和我一样。

不,没有优势,它是一样的,在你的第一个代码片段中你创建了一个 $q.defer() 实例然后你调用它的 resolve() 方法来创建一个 resolved promise.

这是您在使用 异步函数 未来对象 将在未来某个时刻具有不同的值或新数据,您需要知道它何时发生,因为您的应用程序中的相关方可能需要访问 延迟任务 完成时。

现在使用 $http you don't have to do any of that because it will already return a resolved promise that you can directly invoke it's then() 方法时,除非您有不同的做事方式并且需要实施不同的方法。

但并非所有 angularJs 服务都能为您完成这项工作,例如查看 $resource,它包装了 $http 以便在 RESTful 中使用网络 API 场景。 $resource 不会 return 一个 已解决的承诺 ,一个 承诺 是的,你得到了一个,但你需要执行解决它的最后一步 (check this stack question or this and maybe this article about Amber Kaplan's own experience working with Rest)。

所以你做这件事的方式很好,这就是我在使用 $http 时也是这样做的,但是第一个片段代码是我们在搜索时都会搜索的代码将需要对$http做不同的事情,或者强制其他服务“一起工作”或“一样工作”AJAX.