$q 实例分析 Angular 中的 Promise
相信有一些开发经验的朋友就应该知道,对于JavaScript而言,promise十分重要,在开发中总能用到。因此掌握好它是一件必须做的事情。 我之前写过一篇文章,工作总结:jQuery高级应用之Deferred对象,介绍jquery中的promise,因此关于promise的基础介绍就不再详细讲解,这篇文章会重点关注angular中promise的实现。 我们首先有一个简单的html标签,下面的例子都会基于这个标签来书写 <div ng-app="app" ng-controller="demoController as demo"></div> $q在angular中,$q是一个非常重要的service。通过$q,angular有两种比较常用的方式来实现promise,分别是ES6风格与jquery风格。 ES6风格实现我们直接来看看js代码 angular.module('app',[]) .controller('demoController',function($q,$timeout) { var a = 1; $q(function(resolve,reject) { $timeout(function() { if(a == 1) { console.log('resolve'); resolve('hello,JAKE'); } else { console.log('reject'); reject('JAKE is not here!') } },2000) }) .then(function(greeting) { console.log('success,' + greeting); },function(reason) { console.log('failed,' + reason); }) }) 当 "resolve" "success,hello,JAKE" 当 "reject" "failed,JAKE is not here!" 点我查看实例地址 上例中,我直接将第一步逻辑在 然后在对应的逻辑里面,使用resolve/reject标记逻辑的执行状态。then方法中的代码会在第一步的逻辑执行完了才执行,为了证明这一点,我在第一步的逻辑中设置了2秒的延迟。then会等待第一步执行完毕。 then有两个回调函数,分别表示执行成功和执行失败的回调,回调函数的参数为在第一步逻辑中标记方法传入的字符串。如果第一步逻辑执行成功,则会执行then第一个回调函数,如果失败,则会执行第二个回调。 jquery 风格与jquery实现类似,我们需要定义个defer对象,并在第一步逻辑中手动返回promise angular.module('app',$timeout) { var a = 1; $q.when(function() { var defer = $q.defer(); $timeout(function() { defer.notify('notify jake.'); if(a == 1) { console.log('rsolve'); defer.resolve('hello,jake'); } else { console.log('reject'); defer.reject('jake is not here.') } },2000); return defer.promise; }()) .then(function(greeting) { console.log('success,function(reason) { console.log('fail,' + reason); },function(update) { console.log('notify,' + update); }) }) 当 "rsolve" "notify,notify jake." "success,jake" 当 "reject" "notify,notify jake." "fail,jake is not here." 点击我查看实例 Angular 中 Promise 的一些方法,其实从上面的实例就已经能够知道promise的大概用法,不算复杂。 1. then(successCallback,errorCallback,notifyCallback) 2. catch(errorCallback) 3. finally(callback,notifyCallback) 链式操作如果then中逻辑的执行需要时间等待,那么,then中回调函数的返回值为promise对象时,才能够按顺序执行。因此需要我们手动返回一个promise对象,例子如下 var app = angular.module('app',[]); app.controller('demoController',$timeout) { $q.when(function() { var defer = $q.defer(); $timeout(function() { console.log('first'); defer.resolve(); },2000); return defer.promise; }()) .then(function() { var defer = $q.defer(); $timeout(function() { defer.resolve(); console.log('second'); },1000); return defer.promise; }) .then(function() { console.log('third'); }) }); "first" "second" "third" 点我查看实例地址 但是如果then的执行不需要时间等待,then中的回调函数的第一个参数,会获取到上一个then的返回值,然后按顺序执行,如下例。 var app = angular.module('app',$timeout) { function first() { var a = 1; var defer = $q.defer(); $timeout(function() { if(a == 1) { console.log('first resolve'); defer.resolve('resolve result'); } else { console.log('first reject'); defer.reject(); } },2000) return defer.promise; } var promiseA = first(); promiseA.then(function(result) { // $timeout(function() { console.log('second,' + result); return 'document'; // },1000) }) .then(function(result) { console.log('third,' + result); }) }); 输出结果为 "first resolve" "second,resolve result" "third,document" 点我查看实例地址 因为表述起来并不是那么容易,因此建议大家通过实例慢慢理解。 $http$http是对promise的最佳实践。由于controller生命周期会在controller消亡的时候结束,其中的数据也会销毁,因此我们常常会将获取数据的操作放在自定义的服务中。因此我们的实例如下 angular.module('app',function(data) { data.getData().then(function(resp) { console.log(resp); }) }) .factory('data',function($http) { return { getData: function() { var url = 'https://hq.tigerbrokers.com/fundamental/finance_calendar/get_day/2016-06-26'; return $http.get(url); } } }) 我们将then中回调函数的参数打印出来,发现格式如下 Object { config: Object {},data: Object {},headers: function(d) {},status: 200,statusText: 'OK' } 这一点与jquery的返回值略有不同,他们分别表示的意思为
点击查看实例地址 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |