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

今天在写AngularJS Service,然后希望在Controller中使用Service提供Model。架构上,我希望Controller可以直接获得数据,因此有了“同步读取”数据的想法。

但是,我们都知道,在前端做同步读取显然不是好的实践做法,毕竟JavaScript的很多良好体验都是通过异步请求实现的。而且,同步之后会严重影响前端的体验和性能。所以,这里把标题写成“同步读取服务器数据”,更多是吸引眼球。希望刚刚你不是拿着砖头正准备拍的! 

不过,我在网上搜索了一下,还真有人一开始和我想法一样的,见参考资料2。转入正题。

AngularJS提供了一个内置Service $q,它提供了一种承诺/延后(promise/deferred),可以保证我们的调用代码一定能够拿到数据。当然,我们可以猜到,最后去服务器取数据的方式肯定是异步的。只不过这个服务提供了表面上是同步访问的API,当数据获取成功之后,自动将数据提供给调用的代码。

$q – A promise/deferred implementation inspired by Kris Kowal’s Q.

The CommonJS Promise proposal describes a promise as an interface for interacting with an object that represents the result of an action that is performed asynchronously, and may or may not be finished at any given point in time.

话不多说,上代码看看:

1. 创建一个Service,去服务器读取数据:

[javascript]  view plain copy print ?
  1. // $q 是内置服务,所以可以直接使用  
  2. ngApp.factory('UserInfo', ['$http''$q'function ($http, $q) {  
  3.   return {  
  4.     query : function() {  
  5.       var deferred = $q.defer(); // 声明延后执行,表示要去监控后面的执行  
  6.       $http({method: 'GET', url: 'scripts/mine.json'}).  
  7.       success(function(data, status, headers, config) {  
  8.         deferred.resolve(data);  // 声明执行成功,即http请求数据成功,可以返回数据了  
  9.       }).  
  10.       error(function(data, status, headers, config) {  
  11.         deferred.reject(data);   // 声明执行失败,即服务器返回错误  
  12.       });  
  13.       return deferred.promise;   // 返回承诺,这里并不是最终数据,而是访问最终数据的API  
  14.     } // end query  
  15.   };  
  16. }]);  

2. 在Controller上(以同步方式)使用这个Service:

[javascript]  view plain copy print ?
  1. angular.module('ngApp')  
  2.   .controller('MainCtrl', ['$scope''UserInfo'function ($scope, UserInfo) { // 引用我们定义的UserInfo服务  
  3.     var promise = UserInfo.query(); // 同步调用,获得承诺接口  
  4.     promise.then(function(data) {  // 调用承诺API获取数据 .resolve  
  5.         $scope.user = data;  
  6.     }, function(data) {  // 处理错误 .reject  
  7.         $scope.user = {error: '用户不存在!'};  
  8.     });  
  9.   }]);  

欢迎讨论和交流AngularJS及前端开发。

参考资料:

1. ng.$q API文档:http://docs.angularjs.org/api/ng.$q

2. http://stackoverflow.com/questions/17731942/how-to-load-data-synchronously-in-angularjs-application

你可能感兴趣的:(在AngularJS中使用$q同步读取服务器数据)