【问题标题】:Angular: Returning a $q.defer().promise instead of an $http promiseAngular:返回 $q.defer().promise 而不是 $http 承诺
【发布时间】:2015-05-18 22:40:50
【问题描述】:

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

.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;
                });
        }
    };
});

返回$q.defer() 承诺而不是$http 承诺有什么好处吗?这些方法看起来和我一模一样。

【问题讨论】:

  • 我认为这是deferred antipattern;但是,它确实消除了您从控制器中了解$http 对象的需要(即,您不需要知道您真正想要的数据是response.data,而不仅仅是data
  • 你通常做的方式更好更干净,我认为选择第二条路线没有优势。 $http 已经返回了一个承诺,为什么要创建一个新的?
  • 您正在将已解决的承诺添加到已解决的承诺中,这只是多余的。 $q.defer() 更适用于还没有承诺的事情。

标签: angularjs angular-promise angular-http


【解决方案1】:

不,没有优势,都是一样的,在您的第一个代码片段中,您创建了一个 $q.defer() 实例,然后您调用了它的 resolve() 方法来创建一个已解决的承诺

这是您在使用 异步函数未来对象 时需要了解并在 angularJs 中传递的过程未来某个时刻的值或新数据,您需要知道它何时发生,因为您的应用程序中的相关方可能需要在完成时访问 延迟任务的结果。

现在在使用 $http 时,您不必执行任何操作,因为它已经返回了一个 已解决的承诺,您可以直接调用它的 then() 方法,除非您有不同的方法做事的方式,您需要实施不同的方法。

但并非所有 angularJs 服务都会为您完成这项工作,例如查看 $resource,它包装了 $http 以用于 RESTful Web API 场景。 $resource 不会返回一个resolved promise,一个promise 是的,你得到了一个,但你需要做最后一步来解决它(check this stack questionthis 可能还有 this article about Amber Kaplan's own experience working with Rest)。

所以你的做法很好,我在使用$http 时也是这样做的,但第一个 sn-p 代码是我们在需要时都会搜索的代码使用 $http 做不同的事情或强制其他服务“使用”或“一样工作”AJAX。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-04
    • 2017-02-21
    • 2016-02-21
    • 2017-08-04
    • 2017-03-17
    • 2021-01-13
    • 1970-01-01
    • 2019-10-10
    相关资源
    最近更新 更多