zoukankan      html  css  js  c++  java
  • angularJS中XHR与promise

    angularJS应用是完全运行在客户端的应用,我们可以通过angularJS构建一个不需依赖于后端,同时能够实现动态内容和响应的web应用,angularJS提供了将应用与远程服务器的信息集成在一起的方法

    $http服务

    • angularJS提供了内置的$http,$http服务封装了浏览器原生的XMLHttpRequest对象
    • $http,http,$http函数返回一个promise对象,具有success和error两个方法,也可以通过then()处理回调

      复制代码
      //示例:
      $http( {
            url : '/api/user.php',
            method : 'post',
            data : { id : 486 }
      } ).success( function(data,status){
              //当请求响应成功后调用
      } ).error( function(data,status){
             //当请求响应错误后调用
      } );
      
      $http( {
            url : '/api/user.php',
            method : 'post',
            data : { id : 486 }
      } ).then( function(data){
             //当请求响应成功后调用
      }, function(error){
            //当请求响应错误后调用
      } );
      复制代码

    $http参数详解

    • method(字符串)

      指令发送http请求的方式,值有get、post、jsonp、head、delete、put
    • url(字符串)

      请求的目标地址,绝对或相对URL
    • params(字符串map或对象)

      这个键的值是一个字符串map或对象,会被转换成查询字符串追加在URL后面
    • data(字符串或对象)

      这个键的值包含了将要被当作消息体发送给服务器的数据,通常在发送post请求时使用
    • cache(布尔型或缓存对象)

      如果cache属性被设置为true,那么angularJS会用默认的$http缓存来对get请求进行缓存,
      如果cache属性被设置为一个$cacheFactory对象的实例,那么这个实例会被用来对get请求进行缓存
    • responseType(字符串)

      responseType选项会在请求中设置XMLHttpRequestResponseType属性,指定返回数据类型,
      如下可以指定的类型document(http文档)、text(字符串)、json(从json对象解析而来的json字符串)等
    • timeout(数值型或promise对象)

      如果timeout被设置为数值,那么请求将会在超时timeout指定的毫秒数后再发送,
      如果被设置为一个promise对象,当该promise对象被resolve时请求被终止
    • headers

      随请求发送的http头,如headers: {'Content-Type': 'application/x-www-form-urlencoded'}

    $http快捷方法

    • $http.get( url, config );
    • $http.post( url , data , config )
    • $http.jsonp( url, config )

      复制代码
      //为了发送jsonp请求,url地址上必须包含JSON_CALLBACK字样
      $http.jsonp('./api/user.php?callback=JSON_CALLBACK',config).success( function(){
      
      } ).error( function(){
      
      } );
      复制代码
    • $http.put( url, data, config )

    • $http.delete( url, config )

    • $http.head( url, config )

    缓存http请求

    默认$http,向$http的cache配置项传入一个布尔值或缓存实例来启用缓存

    复制代码
    //示例:
    $http.get('./api/user.php',{cache : true}).success( function( data ){
    
    } ).error( function(data){
    
    } );
    
    /*创建一个$cahceFactory对象实例*/
    var cacheInstance = $cacheFactory( 'cacheInstance',{
       capacity : 20    //最新的20个请求被缓存
    } );
    
    $http.get('./api/user.php',{cache : cacheInstance }).success( function( data ){
    
    } ).error( function(data){
    
    } );
    
    //如果要给全局的$http配置缓存,可以通过应用的config()函数给所有$http请求设置一个默认的缓存:
    angular.module('freefedService',[]).config( ['$httpProvider','$cacheFactory',function($httpProvider,$cacheFactory){
             $httpProvider.defaults.cache = $cacheFactory('cacheInstance',{
                 capacity : 20 
             })
    }] );
    复制代码

    拦截器

    • angularJS通过拦截器提供了一个从全局层面对响应进行处理的途径,使用场景:如身份验证、错误处理等
    • 拦截器的核心是服务工厂,通过向$httpProvider.interceptors在$httpProvider进行注册
    • 拦截器有request、response、requestError、responseError四种

      • request

        angularJS通过$http设置对象对请求拦截器进行调用,
        它可以对设置对象进行修改,或者创建一个新的设置对象,
        她需要返回一个更新过的设置对象,或者一个可以返回新的设置对象的promise
      • response

        angularJS通过$http设置对象对响应拦截器进行调用,
        它可以对响应进行修改,或者创建一个新的响应,
        她需要返回一个更新过的响应,或者一个可以返回新响应的promise
      • requestError

        angularJS会在上一个请求拦截器抛出错误,或者promise被reject时调用此拦截器
      • responseError

        angularJS会在上一个响应拦截器抛出错误,或者promise被reject时调用此拦截器

    设置拦截器

    复制代码
    /*创建拦截器*/
    angular.module('freefedService',[]).factory('httpInterceptor',['$q',function( $q ){
            return {
                  request : function( config ){
                       if (config.method.toLocaleLowerCase() == 'post') {
                             config.headers['X-CSRFToken'] = 'unbu12lk9';
                      }
                      return config;       
                  },
                  response : function( response ){
                     return response;
                  },
                  requestError : function( rejection ){ return $q.reject(rejection); },
                  responseError : function( rejection ){
                       if( rejection.status >400 ){
                                 
                       }
                      return $q.reject(rejection);
                  }
           };
    }]);
    
    /*注册拦截器*/
    angular.module('freefedApp',['freefedService']).config(['$httpProvider',function($httpProvider){
          httpProvider.interceptors.push( 'httpInterceptor' );
    }]);
    复制代码

    promise

    • 什么是promise

      promise是抽象异步处理对象以及对其进行各种操作的组件

    • 为什么使用promise

      习惯上,javascript使用闭包或者回调来响应非同步的数据,比如页面全完加载完后,发起获取用户信息的xhr请求,我们可以直接在回调函数中的跟返回的数据进行交互, 而不用关心它什么时候被触发,但是使用回调的痛点也暴露了很多:

      • 回调使得调用不一致得不到保证
      • 当依赖其他回调时,它们篡改代码流程,让代码逻辑复杂,调试变的困难
    • 使用promise带来的改变:

      • 逃脱了回调地狱,promise让异步函数看起来像同步的
      • 可以按照预期来捕获返回值和异常值

        复制代码
        ES6 Promise 示例:
             var xhrFunc = function( options ){
                var options = options || {};
                var method = 'options.method' || 'get';
                var url = options.url || '';
                 return new Promise( function( resolve, reject ){     //创建promise对象并返回
                        var xhr = new XMLHttpRequest();
                        xhr.open(method,url);
                        xhr.onload = function(){
                              if( xhr.status == 200 ){
                                    /*请求成功后,通过resolve()传入数据参数,then 方法对应的成功处理函数可以接收到这个参数值*/
                                    resolve( xhr.responseText );
                             }else{
                                    /*请求出错,通过reject()传入错误信息,then 方法对应的处理错误的函数可以接收到这个错误信息**/
                                    reject( new Error( xhr.statusText ) );
                             }
                        };
                        xhr.onerror = function(){
                                   reject(  new Error( xhr.statusText ) );
                        };
        
                      xhr.send();
                });
          };
        
          xhrFunc( { url : './api/user.php' } ).then( function onFulfilled(  data ){ 
                 /*promise对象被 resolve 时的处理(onFulfilled)*/
                 console.log( data );
          }, function onRejected( error ){
                 /*promise对象被 reject 时的处理(onRejected)*/
                console.log( error );
          }  );
        复制代码
    • angular中的promise

      • 如何创建angularJS中的promise 通过使用内置的$q,$q在它的deferred API中提供了一些方法,通过创建一个deferred对象,deferred对象暴露三个方法和一个可以处理promise的promise属性:
      • resolve( value )

        resolve函数用这个value值来执行deferred promise
      • reject( reason )

        reject函数用一个原因来拒绝dererred promise,它等于使用一个拒绝来执行一个promise
      • notify( value )

        用promise的执行状态来进行响应,
        如我们要从promise返回一个状态进度,可以使用notify()函数来传送它
      • promise

           var deferred = $q.defer();  //调用$q服务的defer方法创建一个defer对象
           deferred.promise    //通过访问promise属性得到promise对象
    • promise中方法

      • then(successFn,errFn,notifyFn)

        无论promise成功还是失败了,当结果可用之后,
        then都会立刻异步调用successFn或者errFn,  
        在promise被执行或拒绝之前,notifyFn回调可能会被调用0到多次,以提供过程状态的提示
      • catch( errFn );

        可以通过catch捕获错误,替代then中的errFn

    示例代码:

    复制代码
    demo.html
    
    <!doctype html>
    <html ng-app="freefedApp">
       <head>
            <title>angular应用demo</title>
            <script src="angular.js"></script>
            <script src="service.js"></script>
            <script src="app.js"></script>
      </head>
      <body>
      <div ng-controller="userCtrl">
          <div class="user-center">
                 <span class="user-icon"><img src="{{vm.user.pic}}" /></span>
                 <span class="user-name">{{vm.user.name}}</span>
          </div>
       </div>
      </body>
    </html>
    复制代码
    复制代码
    //service.js
    
    angular.module('freefedService',[]).factory('ajaxService',['$http','$q',function($http,$q){
             var deferred = $q.defer();
             return function(params){
                   var params = params || {};
                   $http({
                       method : params.method || 'post',
                       url : params.url || '',
                       data : params. data || {},
                       responseType : params.type || 'json'
                   }).success(function(data){
                       deferred.resolve(data);
                   }).error(function(reason){
                       deferred.reject(reason);
                   });
                   return deferred.promise()
              };
       }]);
    
    
    //app.js
    
    /*声明module*/
    var module = angular.module('freefedApp',['freefedService']);
    
    /*声明控制器*/
    module.controller('userCtrl',['$scope','ajaxService',function($scope,ajaxService){
          var vm = $scope.vm = $scope.vm || {};
          vm.user = {};
          //调用ajaxService服务
          ajaxService( {
               url : '/getUser.php'
         } ).then(function(data){
                vm.user.pic= data.pic;
                vm.user.name = data.name;
           },function(error){
               alert( error.msg );
           }
        );
    }]);
  • 相关阅读:
    JS深度判断两个数组对象字段相同
    box-shadow inset
    swiper实现滑动到某页锁住不让滑动
    vuex上手文章参考
    js基础补漏
    react学习文章
    C# .Net String字符串效率提高-字符串拼接
    JS,Jquery获取各种屏幕的宽度和高度
    highcharts的dataLabels如何去处阴影
    .net C# 抽奖,中奖
  • 原文地址:https://www.cnblogs.com/huangshikun/p/7060818.html
Copyright © 2011-2022 走看看