angularjs $q & $http 关于承诺

angularjs $q & $http about promise

关于官方文档中的$http:

The $http API is based on the deferred/promise APIs exposed by the $q service.

The $http service is a function which takes a single argument — a configuration object — that is used to generate an HTTP request and returns a promise

那么下面的代码是什么意思:

var deferred = $q.defer();
var promise = deferred.promise;
var progress;
$http.get("https://api.github.com/repos/angular/angular.js/pulls")
.success(function(data){
    var result = [];
    for(var i = 0; i < data.length; i++){
        result.push(data[i].user);
        progress = (i+1)/data.length * 100;
        deferred.notify(progress);
    }
    deferred.resolve(result);
    })
.error(function(error){
    deferred.reject(error);
});
return promise;

如果 $http return 是一个承诺,我为什么要使用 $q 来 return 一个承诺?

$http 是 returning 一个承诺,我们使用它并因此得到 'success'(也可以使用 'then')。如果您在服务中使用此 $http 调用并从您的控制器调用此服务方法,那么您将希望 return 来自该方法的承诺,因此您可以使用 .then 和 .catch 等

一个deferred的新实例是通过调用$q.defer()构造的。 延迟对象的目的是公开关联的 Promise 实例以及 API

可用于指示成功不成功完成,以及 任务。

$q 与 angular 中的 $rootScope.Scope 范围模型观察机制集成,这意味着分辨率或拒绝更快地传播到您的模型中,并避免不必要的浏览器重绘,这会导致闪烁UI.

参考:官方文档

推荐的$http服务使用方式如下:

$http({
  method: 'GET',
  url: '/someUrl'
}).then(function successCallback(response) {
    // success code here
  }, function errorCallback(response) {
    // error handling code here
  });

在这种情况下,您不必 return 一个新的承诺,但可以 return 调用 then() 的结果,正如您所期望的那样。

但是,success() 方法是一种便捷方法,它已将响应对象的字段作为单独的参数传递:

.then(function(response) {
  // do something with response.data, response.status, etc.
})

对比

.success(function(data, status, headers, config) {
  // do something with data, status, etc.
})

然而,与 then() 相比,success() 没有 return 承诺。我不建议使用它,我刚刚在 the docs 中看到它现在已被弃用。

更新: 我认为在您提供的示例中构建另一个承诺的原因不是可以使用 success() 而是调用 deferred.notify(progress) 是可能的。如果不显式创建另一个承诺,您将无法访问 deferred 对象。