AngularJS中的$http、$q服务和promise对象的联系

原创 2016年08月09日 15:41:25

一、介绍:


$http服务是AngularJS系统自带的,可以用来进行网络通信、获取远程服务器的数据。要记住的是,$http是对浏览器XMLHttpRequest的封装,也就是说,它其实是Ajax。

首先为了用$http发起请求,我们得先找到一个可以测试的API,这里我用:https://randomuser.me/api/来测试:用get请求,它能够返回json格式的一个随机用户的资料。具体的介绍就不说了,大家可以看看这个网页:https://randomuser.me/。比如我在浏览器中输入,可以看到返回的数据:
测试API

二、$http的基本用法:


使用的时候写好几个参数:

  • options:包括url、method(get或post)
  • successFn:成功的回调
  • errorFn:失败的回调

格式:

$http(options).success(successFn).error(errorFn)

例子:(html文件就是一个按钮和显示结果的文本框,在这里就不写出来了)

angular.module('myDemo', [])

    .controller('myController', ['$scope', '$http', function ($scope, $http) {
        $scope.testHttp = function () {
            $http({
                method: 'GET',
                url: 'https://randomuser.me/api/'
            }).success(function (data) {    // 这里的data的类型是object,并且,它已经是返回数据的“数据”部分(如暂时不理解,后面会说到)
                console.log(angular.toJson(data, true));
                $scope.result = data;
            }).error(function (err) {
                console.log(err);
            })
        }
    }]);

这里,$http(options)返回的是一个被封装的promise对象,我们可以console.log出来看看:
$http返回的promise对象
可以看到,黑色部分圈起来的是基本的promise部分(拥有then,catch,finally函数),除了这些函数以外,这个promise对象还有success和error函数(见红色横线),这是$http返回的时候封装的,供我们使用的时候更方便。比如上述例子中,注释里说,success的回调函数返回的data直接就是我们想要的“数据部分”,那么如果我用的是then,那么返回的除了数据部分,还有额外的部分(比如状态码),这时候我就得自己拿出这个“数据部分”,代码如下:

var promise = ...;  // 省略$http过程

promise.then(function (data) {
        // realData被包含在data的“data”字段中,一般它才是我们想要的
        var realData = data.data;
        console.log(realData);
    }, function (err) {

    });

三、$q的介绍与用处:


在上述例子中,我们是在Controller层写了网络请求。但是我们知道,在AngularJS的MVC框架之中,业务逻辑(包括网络请求)的部分应该尽可能写到Service层中,而让Controller的逻辑尽可能少。但是,怎么把网络请求最终得到的有用的数据,返回给controller呢?这里有两种思路:

  • 方法一:把$http(options)返回的promise对象直接在Service中返回。在controller中拿到之后,再写success和error的回调。
  • 方法二:在Service中返回一个自定义的promise对象,用来回调给controller。这里的回调者,由$q创建的“defered”对象来担任。

方法一写起来比较简单,在这里就不演示了。
在演示方法二之前,先简单介绍一下AngularJS的qq服务是在AngularJS中用来创建promise对象的,但它首先创建一个defered对象:

var defered = $q.defer();

打印该defered对象:
defered对象属性一览
可以看到它有3个方法:resolve,reject,notify,分别对应于接受、拒绝、通知,具体用法在这里就不说了。还有一个promise属性,它的值就是一个基本的promise对象,主要用来返回。比如上面的例子,我可以这样写:

services.js

...
    .factory('userService', ['$http', '$q', function ($http, $q) {

        var userService = {};   // 返回的服务

        this.urlForRandomUser = "https://randomuser.me/api/";

        var that = this; // 获取当前作用域,下面要用到
        userService.getRandomUser = function () {

            var defered = $q.defer();

            $http.get(that.urlForRandomUser)
                .success(function (data) {
                    defered.resolve(data.results[0]);
                })
                .error(function (err) {
                    defered.reject(err);
                });
            return defered.promise; // 把defered对象中的promise对象返回出来
        };

controllers.js

...
    .controller('firstController', ['$scope', 'userService', function ($scope, user) {

        $scope.getUser = function () {

            function success(data) {
                var str = angular.toJson(data, true);   // 用angular的格式化json的方法,更为清晰
                $scope.result = str;
            }

            function error(err) {
                $scope.result = err;
                alert('error occured!\n' + err);
            }

            // 注意这里不能用success或error函数,用then就好
            user.getRandomUser().then(success, error);
        }

    }])

要注意的是最后那里,defered的promise是基本的promise对象,并没有success和error函数,所以要用then来执行回调。

版权声明:本文为博主原创文章,未经博主允许不得转载。

$q -- AngularJS中的服务

既然是用来处理异步编程的,那么在浏览器端的JS里,主要是2种: setTimeout 和 Ajax 请求. promise 的使用就很像Ajax请求的成功和失败回调。 此承诺/延迟(promise...
  • renfufei
  • renfufei
  • 2014年02月13日 22:02
  • 77035

Angular $q 完全指南

本文转自:点击打开链接 如果想使用 $http 或者其他异步操作, 那 $q 是必须要掌握的概念啦. Let's get started! 如何理解$q, deferred obj...
  • zhuyucheng123
  • zhuyucheng123
  • 2016年01月27日 23:33
  • 3805

listener.ora 、sqlnet.ora 、tnsnames.ora的关系以及手工配置举例

解决问题:TNS或者数据库不能登录。 最简单有效方法:使用oracle系统提供的工具 netca 配置(把原来的删除掉重新配置) $netca 俺仍有的疑问: 如何指定'listen...
  • jlds123
  • jlds123
  • 2011年03月10日 11:32
  • 696

angular中$q.all用法

$q.all是用于执行多个异步任务进行回调,它可以接受一个promise的数组,或是promise的hash(object)。任何一个promise失败,都会导致整个任务的失败。 例1:接受一个pr...
  • shidaping
  • shidaping
  • 2016年09月01日 13:49
  • 5421

前端框架天下三分:Angular React 和 Vue的比较

前端这几年的技术发展很快,细分下来,主要可以分成四个方面: 1.开发语言技术,主要是ES6&7,coffeescript,typescript等;  2.开发框架,如Angular,React...
  • q6678188
  • q6678188
  • 2017年05月09日 14:40
  • 1946

angular中的$http服务及promiseA+规范总结

我们可以使用内置的http服务直接同外部进行通信。http服务直接同外部进行通信。http服务只是简单的封装了浏览器原生的XMLHttpRequest对象。1、链式调用http服务是只能接受一个参数的...
  • osdfhv
  • osdfhv
  • 2017年03月09日 15:31
  • 593

angularJS中的promise模式以及通过$q解决异步

引言 说到promise,不得不说的就是回调函数 那么什么是回调函数呢? function test(callback){//有一个叫做test的function var a=1; ...
  • Sourcecode_poet
  • Sourcecode_poet
  • 2016年12月07日 20:22
  • 1583

在AngularJS中使用$q同步读取服务器数据

今天在写AngularJS Service,然后希望在Controller中使用Service提供Model。架构上,我希望Controller可以直接获得数据,因此有了“同步读取”数据的想法。 ...
  • lglgsy456
  • lglgsy456
  • 2014年06月19日 17:11
  • 42433

Angularjs Promise 解决异步获取数据导致return返回为空的问题

最近在开发项目的时候。我在service中请求数据返回给控制器的时候,由于数据是异步请求的,这里需要知道javascript的运行环境是单线程的,一次只能执行一个任务,但是单线程坏处就是如果前一个任务...
  • fanxw1984
  • fanxw1984
  • 2016年11月15日 15:37
  • 2971

angularjs promise理解与使用

本文在于对angularJs中的promise模式进行一个简单理解与使用,方便快速上手。
  • qq_18325731
  • qq_18325731
  • 2016年09月14日 17:54
  • 1463
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:AngularJS中的$http、$q服务和promise对象的联系
举报原因:
原因补充:

(最多只允许输入30个字)