AngularJS $q 和 $q.all 单个数据源和多个数据源合并(promise的说明)
这篇文章讲的不错, angular $q 和 promise!!
--------------------------------------------------------------
通过调用 $q.defer() 可以构建一个新的 deffered 实例。
deffered 对象用来将 Promise 实例与 标记任务状态(执行成功还是不成功)的 API 相关联。
deffered 对象的方法
- resolve(value) ——传入 value 解决派生的 promise。 如果 value 是一个通过 $q.reject 构造的拒绝对象(rejection) , 该promise 将被拒绝。
- reject(reason) ——拒绝派生的promise,并提供原因 。 这相当于通过 $q.reject构造的拒绝对象(rejection)作为参数传递给 resolve。
- notify(value) ——在 promise 执行的过程中提供状态更新。 这在 promise 被解决或拒绝之前可能会被多次调用。
deffered 对象的属性
promise – {Promise} —— 与延迟(deferred)相关联的 promise 对象。
承诺 接口 | Promise API
当创建 deferred 实例时会创建一个新的 promise 对象,并可以通过 deferred.promise 得到该引用。
promise 对象的目的是在 deferred 任务完成时,允许感兴趣的部分取得其执行结果。
promise 对象的方法
- then(successCallback, errorCallback, notifyCallback) ——不管 promise 是被处理还是被拒绝, 一旦结果可用,then 就会尽快地异步调用 成功/错误 回调函数 只要结果是可用的。 调用回调函数时传递单个参数: 结果 或拒绝的理由。 此外,notify 回调可能被调用 0到多次,以提供 提供一个进度指示,之前承诺解决或拒绝。
这个方法 返回一个新的promise 对象, 根据 successCallback , errorCallback的返回值进行解决或拒绝 。 它还通过 notifyCallback 方法的返回值进行通知。 promise 不能从notifyCallback方法得到解决或拒绝 。
- catch(errorCallback) —— promise.then(null, errorCallback) 的快捷方式
- finally(callback) ——让你可以观察到一个 promise 是被执行还是被拒绝, 但这样做不用修改最后的 value值。 这可以用来做一些释放资源或者清理无用对象的工作,不管promise 被拒绝还是解决。 更多的信息
因为在 ES3版本的JavaScript中 finally 是一个保留字关键字,不能作为属性名,为了适配 IE8,您需要使用 promise['finally'](callback) 这种形式来调用该方法。
研究了一下$q回调服务,看来半天都是似懂非懂的样子,感觉实现了异步加载的功能,还是动手试验并记录下来,如果不对欢迎指正(后台是ASP.Net Web API模拟的)
第一种情况的回调,对单个数据源的请求
1 | myApp.factory( 'myService' , function ($http, $q) { <br> return { <br> getAllData: function () { <br> //定义一个回调服务 <br> var deferred = $q.defer(); <br> $http.get('/API/Values')//此时获取的是单个数据源 <br> .success(function (result) { <br> //将结果委托回调函数 <br> deferred.resolve(result); <br> }) <br> .error(function (result) { <br> debugger; <br> }); <br> //返回回调函数结果 <br> return deferred.promise; <br> } <br> }; <br> }); <br> function FetchCtrl($scope, $http, $templateCache, myService, myServiceAll) { <br> <br> $scope.fetch = function () { <br> <br> var result = myService.getAllData(); <br> //通过回调函数结果得到数据值 <br> result.then(function (data) { <br> $scope.result = data; <br> }; <br> <br> } <br>} |
第二种情况的回调,对多个数据源的请求,最后同时将多个结果集合并一起返回
1 | //服务声明 <br> myApp.factory('myServiceAll', function ($http, $q) { <br> return { <br> getAllData: function () { <br> //定义一个回调服务 <br> var deferred = $q.defer(); <br> //定义两个获取的源路径 <br> var p1 = $http.get('/API/Values'); <br> var p2 = $http.get('/API/Values/0'); <br> $q.all([p1, p2]) <br> .then(function (results) { <br> var aggregatedData = []; <br> angular.forEach(results, function (result) { <br> aggregatedData = aggregatedData.concat(result.data); <br> }); <br> //将结果委托回调函数 <br> deferred.resolve(aggregatedData); <br> }); <br> //返回回调函数结果 <br> return deferred.promise; <br> } <br> } <br> }); <br> <br> function FetchCtrl($scope, $http, $templateCache, myService, myServiceAll) { <br> <br> $scope.fetch = function () { <br> //通过回调函数结果得到数据值 <br> var result = myServiceAll.getAllData(); <br> result.then(function (data) { <br> <br> $scope.result = data; <br> }) <br> }; <br> <br> } |
方法简介
$q service 四个方法函数 , 按照个人理解划分为三类。
-
非链式调用
$q.when(value)
传递变量值,promise.then()执行成功回调
$q.all(promises)
多个promise必须执行成功,才能执行成功回调,传递值为数组或哈希值,数组中每个值为与Index对应的promise对象。
-
错误信息传递
$q.reject(reason)
返回一个失败原因,promise.then()执行失败回调
-
链式调用
$q.defer()
返回一个deferred对象
- resolve(value) – 简化说明 配置该deferred对象promise的成功调用函数参数
- reject(reason) – 简化说明 配置该deferred对象promise的失败调用函数参数
- promise - 简化说明 配置后的promise对象
个人理解说明
链式调用内部的默认失败回调会向后传递异常,所以为避免麻烦,且不在意每一处的业务逻辑错误,不要在每一处then()处声明异常处理函数,在最后一个 then()中声明即可。
promiseX.then(function(){}).then(function(){})
.then(function(val){},function(reason){})
如果在意每一处可能出现的业务逻辑错误,在回调中return $q.reject();传递错误.无论执行哪一个回调函数,如果内部没有人为return $q.reject();,则若没有执行错误,暨返回成功信号。
1 | var deferred = $q.defer();<br> deferred.resolve(1);<br> var promiseA = deferred.promise;<br>promiseA<br> .then( function (val){$log.info(val); return ++val;})<br> .then( function (val){$log.info(val); return ++val;})<br> .then(<br> function (val){$log.info(val); return ++val;},<br> function (val){$log.info(val)}<br> ); |
链式调用完成后控制台打印出 1,2,3
1 | var deferred = $q.defer();<br> deferred.resolve(1);<br> var promiseA = deferred.promise;<br>promiseA<br> .then( function (val){$log.info(val); return $q.reject(15);})<br> .then( function (val){$log.info(val); return ++val;})<br> .then( function (val){$log.info(val); return ++val;})<br> .then( function (val){$log.info(val); return ++val;})<br> .then(<br> function (val){$log.info(val); return ++val;},<br> function (val){$log.info(val)}<br> ); |
链式调用完成后控制台打印出 1,15,可以看出,第一个return $q.reject(15)之后,直到最后一个then()才有错误回调函数,所以异常一直传递到最后,中间的几个then()没有错误回调函数。
1 | $q.when( 'I Love you!' )<br> .then( function (value){$log.info(value)}); |
控制台打印出I Love you!;
1 | $q.when($q.reject( 'I Hate you!' ))<br> .then( null , function (value){$log.info(value)}); |
控制台打印出I Hate you!;
1 | var promiseA = $q.when( 'I Love you!' );<br> var promiseB = $q.when( 'Love story!' );<br> var promiseC = $q.when( "Let't get wet!" );<br> $q.all([promiseA,promiseB,promiseC]).then( function (value){<br> value[0].then( function (value){$log.info(value);})<br> value[1].then( function (value){$log.info(value);})<br> value[2].then( function (value){$log.info(value);})<br> }) |
控制台打印出I Love you!,Love story!,"Let't get wet!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现