1. 程式人生 > >angularJS中XHR與promise

angularJS中XHR與promise

local rip ole nload 暴露 -s www intercept XML

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

angularJS中XHR與promise