angularJS中XHR與promise

angularJS應用是徹底運行在客戶端的應用,咱們能夠經過angularJS構建一個不需依賴於後端,同時可以實現動態內容和響應的web應用,angularJS提供了將應用與遠程服務器的信息集成在一塊兒的方法

$http服務

  • angularJS提供了內置的$http,$http服務封裝了瀏覽器原生的XMLHttpRequest對象
  • $http,http,$http函數返回一個promise對象,具備success和error兩個方法,也能夠經過then()處理回調javascript

    複製代碼
    //示例: $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(字符串)php

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

    請求的目標地址,絕對或相對URL
  • params(字符串map或對象)java

    這個鍵的值是一個字符串map或對象,會被轉換成查詢字符串追加在URL後面
  • data(字符串或對象)web

    這個鍵的值包含了將要被看成消息體發送給服務器的數據,一般在發送post請求時使用
  • cache(布爾型或緩存對象)ajax

    若是cache屬性被設置爲true,那麼angularJS會用默認的$http緩存來對get請求進行緩存,
    若是cache屬性被設置爲一個$cacheFactory對象的實例,那麼這個實例會被用來對get請求進行緩存
  • responseType(字符串)json

    responseType選項會在請求中設置XMLHttpRequestResponseType屬性,指定返回數據類型,
    以下能夠指定的類型document(http文檔)、text(字符串)、json(從json對象解析而來的json字符串)等
  • timeout(數值型或promise對象)後端

    若是timeout被設置爲數值,那麼請求將會在超時timeout指定的毫秒數後再發送,
    若是被設置爲一個promise對象,當該promise對象被resolve時請求被終止
  • headersapi

    隨請求發送的http頭,如headers: {'Content-Type': 'application/x-www-form-urlencoded'}

$http快捷方法

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

    複製代碼
    //爲了發送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 ); } ); }]);
相關文章
相關標籤/搜索