AngularJS - why promises ($q) with $http?

我与影子孤独终老i 提交于 2019-11-29 23:19:22

Usually you'll deal with asynchronous tasks in Javascript with callbacks;

$.get('path/to/data', function(data) {
  console.log(data);
});

It works fine, but start to complicate when you go into whats called the 'callback hell';

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

The alternative is working with promises and defered object;

Deferreds - representing units of work
Promises - representing data from those Deferreds

Sticking to this agenda can assist to you in every extreme asynctask case:

  1. You have a regular call that need to get data from the server, manipulate it, and return to the scope
  2. You have multiple calls that each is depending on the precious one (cahin strategy)
  3. You want to send multiple (parallel) calls and handle their success in 1 block
  4. You want your code to be orginized (prevent dealing with handling results on controllers)

Your task is the easiest one to handle with $q and $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;
 }

And calling the service function is the same

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

You can handle the error like this:

get('http://myservice.com/JSON/')
    .then(function (data) {
        // do something with data
    },
    function (error) {
        //do something with error
    });

But unfortunately since you have already caught the error then the final error won't be triggered. You will also have the same problem with success.

To get that to work you ned to use $q.

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

Also there is no need to pass in success and error functions because you can use promises instead.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!