var ngApp=angular.module('ngApp',[]); /******************************************************************* * $q爲內置服務 ****************************************************************/ ngApp.factory('UserInfoService',['$http','$q',function($http,$q){ return{ query:function(){ var defer=$q.defer(); //聲明延後執行 $http({method:'GET',url:'data/students.json'}). success(function(data,status,headers,config){ defer.resolve(data); //聲明執行成功 console.log('UserInfoService success'); }). error(function(data,status,headers,config){ defer.reject(); //聲明執行失敗 }); return defer.promise; //返回承諾,返回獲取數據的API } } }]); ngApp.controller('MainCtrl',['$scope','UserInfoService',function($scope,UserInfoService){ var promise = UserInfoService.query(); //同步調用,獲取承諾接口 promise.then(function(data){ $scope.user=data; //調用承諾接口resolove() console.log('MainCtrl ...'); },function(data){ $scope.user={error:'數據不存在。。。'}; //調用承諾接口reject(); }); }]);
promise是一種用異步的方式處理值的方法,promise是對象,表明了一個函數最終可能的返回值或者拋出的異常,在與遠程對象打交道時咱們能夠把他看做是遠程對象的一個代理。 若是說是promise也是異步處理方式的一種,那麼咱們會想起它和XHR和$.ajax有啥區別呢? javascript
習慣上js使用閉包或者回調來相應非同步返回的數據,好比頁面加載以後的XHR請求。咱們能夠跟數據進行正常交互,就好像它已經返回了同樣,而不須要依賴回調函數的觸發。java
那麼ng提出的promise是爲了解決什麼問題呢? 回調已經被使用了很長時間,一般若是有回調依賴其餘還回調時將會時調試變得很是艱難,每一步調用以後都須要顯示處理錯誤。與之不一樣的是promise提供了另一個抽象:這些函數返回promise對象。angularjs
從必定層面上看ng改變的不是簡單的改變代碼風格,而是讓我對一些思惟習慣發起了反思和改善。ajax
User.get(fromId,{ success:function(){ user.friends.find(toId,function(){}) }, failure:function(){} })
User.get(fromId). then(function(user){ },function(err){ }). then(function(){},function(){});
使用了promise的收穫之一是逃脫了回調的固定思惟邏輯。promise讓異步處理的機制看上去更像是同步,基於同步函數咱們能夠按照預期來捕獲返回值和異常值。能夠在程序中的任什麼時候刻捕捉錯誤,而且繞過依賴於程序異常的後續代碼,咱們不須要思考這個同步帶來的好處。所以使用promise的目的是:獲取功能組合和錯誤冒泡能力的同時,保持代碼異步運行的能力。json
promise是頭等對象,自帶了一些約定。promise
想要在angularjs中建立promise,能夠使用內置的$q服務,$q服務在它的deferred API中提供了一些方法。閉包
首先把它注入到你想使用它的對象中異步
angular.module('ngApp',[]). factory('UserInfoService',['$q',function($q){ //code here }])
要建立一個deferred對象,能夠調用defer()方法; var deferred= $q.defer();函數
deferred對象暴露了三個方法,以及一個能夠用於處理promise的promise屬性。url
GitHubService.then(function(data){ }).then(function(data){ $scope.Users=data; });