AngularJS - 为什么用$ http承诺($ q)?

kel*_*dar 11 deferred angularjs

我在从jQuery转换几年后学习AngularJS.有些位更加直观.有些不是很多:).

我试图了解承诺的使用,特别是使用$ http的$ q,并且似乎没有太多关于这两个组合的信息,我可以找到.

为什么我会使用promises代替成功/错误回调?他们都在现实中使用回调,那么为什么承诺会更好?我可以设置get(...)如下函数:

function get(url, success, error) {
    success = success || function () {};
    error = error || function () {};

    $http.get(url)
        .success(function (data) {
            success(data);
        })
        .error(function (error) {
            error(error);
        });
}

get('http://myservice.com/JSON/',
    function () {
        // do something with data
    },
    function () {
        // display an error
    }
);
Run Code Online (Sandbox Code Playgroud)

哪个好(?)因为它让我可以完全控制正在发生的事情.如果我打电话,get(...)那么我可以在任何地方控制任何成功/错误get.

如果我将其转换为使用promises,那么我得到:

function get(url) {
    return $http.get(url)
        .then(function (data) {
            return data;
        },
        function (error) {
            return error;
        });
}

get('http://myservice.com/JSON/')
    .then(function (data) {
        // do something with data
    });
    // cannot handle my errors?
Run Code Online (Sandbox Code Playgroud)

哪个是浓缩的,我同意; 我们也不必明确担心成功/错误回调,但我似乎已经失去了对我的错误回调的控制,因为我无法配置第二个回调来处理错误.

这意味着如果我在可以由多个控制器使用的服务中使用此功能,那么我无法更新UI以警告用户出错.

我错过了什么吗?承诺是首选的是有原因吗?我找不到一个例子为什么.

Ben*_*ant 24

通常你会用Javascript处理回调中的异步任务;

$.get('path/to/data', function(data) {
  console.log(data);
});
Run Code Online (Sandbox Code Playgroud)

它工作正常,但当你进入什么称为'回调地狱'时,开始变得复杂;

$.get('path/to/data', function(data) {
  $.get('path/to/data2' + data, function(data2) {
    $.get('path/to/data3' + data2, function(data3) {
      manipulate(data, data2, data3);
    }, errorCb);
  }, errorCb);
}, errorCb);
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用承诺和延迟对象;

Deferreds - representing units of work
Promises - representing data from those Deferreds
Run Code Online (Sandbox Code Playgroud)

坚持这个议程可以帮助你处理每一个极端的asynctask案例:

  1. 您有一个需要从服务器获取数据,操作它并返回范围的常规调用
  2. 你有多个电话,每个电话都依赖于宝贵的电话(cahin策略)
  3. 您希望发送多个(并行)调用并在1个块中处理它们的成功
  4. 您希望对代码进行组织化(防止处理控制器上的处理结果)

使用$ q和$ http处理您的任务最简单

function get(url) {
    var deferred = $q.defer();
    $http.get(url)
        .success(function (data) {
            deferred.resolve(data);
        })
        .error(function (error) {
            deferred.reject(error);
        });

    return deferred.promise;
 }
Run Code Online (Sandbox Code Playgroud)

并且调用服务功能是一样的

get('http://myservice.com/JSON/')
.then(function (data) {
    // do something with data
});
// cannot handle my errors?
Run Code Online (Sandbox Code Playgroud)