Promise in AngularJS-程序员宅基地

技术标签: 前端开发  promise  angularjs  

What's promise

Angular’s event system provides a lot of power to our Angular apps. One of the most powerful features that it enables is automatic resolution of promises.

Promises are a method of resolving a value or not in an asynchronous manner. Promises are objects that represent the return value or a thrown exception that a function may eventually provide.

Promises are incredibly useful in dealing with remote objects and we can think of them as a proxy for them.

 
Promises are first-class objects and carry with them a few  guarantees:
  • Only one resolve or reject will ever be called
– resolve will be called with a single fulfillment value
– reject will only be called with a single rejection reason
  • If the promise has been resolved or rejected, any handlers depending upon them will still be called
  • Handlers will always be called asynchronously
Additionally, we can also chain promises and allow the code to process as it will normally would run. Exceptions from one promise bubble up through the entire promise chain.
They are always asynchronous, so we can use them in the flow of our code without worry that they will block the rest of the app.

Promise in AngularJS

Angular’s event-loop gives angular the unique ability to resolve promises in it’s $rootScope. $evalAsync stage (see under the hood for more detail on the run loop). The promises will sit inert until the $digest run loop finishes.

bind promise and view directly

This allows for Angular to turn the results of a promise into the view without any extra work. It enables us to assign the result of an XHR call directly to a property on a $scope object and think nothing of it. For instance, we might have a list of friends in a view, like so:

< ul>
  < li ng-repeat= "friend in friends">
     { { friend. name }}
  </ li>
</ ul>
 
If we have a service that returns a promise , we can simply place the promise in the view and expect that Angular will resolve it for us:
angular.module( 'myApp', [])
 .controller( 'DashboardController', [ '$scope''UserService'function($scope, UserService) {
     // UserService's getFriends() method
     // returns a promise
    $scope.friends  = User.getFriends( 123);
 }]);
 
When the asynchronous call to getFriends returns, the $scope.friends value will automatically update the view.
 

How to create a promise

In order to create a promise in Angular, we’ll use the built-in $q service. The $q service provides a few methods in it’s deferred API.

1. inject $q service

First, we’ll need to inject the $q service into our object where we want to use it.

angular.module( 'myApp', [])
   .factory( 'UserService', [ '$q'function($q) {
    // Now we have access to the $q library
 }]);
 

2. $q.defer()

To created a deferred object, we’ll call the method defer():
var deferred  = $q.defer();
 
The deferred object exposes  three methods and the  single promise property that can be used in dealing with the promise.
  • resolve(value)
The resolve function will resolve the deferred promise with the value.
deferred .resolve({name :  "Ari", username :  "@auser"});
 
  • reject(reason)
This will reject the deferred promise with a reason. This is equivalent to resolving a promise with a rejection
deferred .reject( "Can't update user");
// Equivalent to
deferred.resolve( $q.reject( "Can't update user"));
 
  • notify(value)
This will respond with the status of a promises execution.
TODO: Add notify example
  • promise property
We can get access to the promise as a property on the deferred object:
deferred.promise
 
A full example of creating a function that responds with a promise might look similar to the following method on the UserService as mentioned above.
angular.module( 'UserService', [ '$q'function($q) {
  var getFriends  =  function(id) {
    var deferred  =  $q.defer();
 
    // Get friends from a remote server
   $http.get( '/user/'  + id  +  '/friends')
   .success( function(data) {
       deferred.resolve(data.friends);
   })
   .error( function(reason) {
       deferred.reject(reason);
   });
 
   return  deferred.promise;
 }
 }]);
 

3. interact with promise

Now we can use the promise API to interact with the getFriends() promise.
In the case of the above service, we can interact with the promise in two different ways.
  • then(successFn, errFn, notifyFn)
Regardless of the success or failure of the promise, then will call either the  successFn or the  errFnasynchronously as soon as the result is available. The callbacks are always called with a single argument: the result or the rejection reason.
The  notifyFn callback may be called zero or more times to provide a progress status indication before the promise is resolved or rejected.

The then() method always returns a new promise which is either resolved or rejected through the return value of the successFn or the errFn. It also notifies through the notifyFn.

  • catch(errFn)
This is simply a helper function that allows for us to replace the err callback with  .catch(function(reason){}):
$http.get( '/user/'  + id  +  '/friends')
 . catch( function(reason) {
    deferred.reject(reason);
 });
 
  • finally(callback)
This allows you to observe the fulfillment or rejection of a promise, but without modifying the result value. This is useful for when we need to release a resource or run some clean-up regardless of the success/error of the promise.
We cannot call this directly due to finally being a reserved word in IE javascript. To use finally, we have to call it like:
promise[ 'finally']( function() {});
 
 
Angular’s $q deferred objects are chainable in that even then returns a promise. As soon as the promise is resolved, the promise returned by then is resolved or rejected.
These promise chains are how Angular can support $http’s interceptors.
The $q service is similar to the original Kris Kowal’s Q library:
  1. $q is integrated with the angular $rootScope model, so resolutions and rejections happen quickly inside the angular
  2. $q promises are integrated with angular’s templating engine which means that any promises that are found in the views will be resolved/rejected in the view
  3. $q is tiny and doesn’t contain the full functionality of the Q library

$q library

The $q library comes with several different useful methods.

all(promises)

If we have multiple promises that we want to  combine into a single promise, then we can use the $q.all(promises) method to combine them all into a single promise. This method takes a single argument:
promises (array or object of promises)
 
Promises as an array or hash of promises
The all() method returns a single promise that will be resolved with an array or hash of values. Each value will correspond to the promises at the same index/key in the promises hash. If any of the promises are resolved with a rejection, then the resulting promise will be rejected as well.

defer()

The defer() method creates a deferred object. It takes no parameters. It returns a new instance of a single deferred object.

reject(reason)

This will create a promise that is resolved as rejected with a specific reason. This is specifically designed to give us access to forwarding rejection in a chain of promises.

This is akin to throw in javascript. In the same sense that we can catch an exception in javascript and we can forward the rejection, we’ll need to rethrow the error. We can do this with $q.reject(reason).

This method takes a single parameter:

reason (constant, string, exception, object)
The reasons for the rejection.
This reject() method returns a promise that has already been resolved as rejected with the reason.

when(value)

The when() function wraps an object that might be a value then-able promise into a $q promise.  This allows for us to deal with an object that may or may not be a promise.
The when() function takes a single parameter:
value
This is the value or a promise
The when() function returns a promise that can be then used like any other promise.
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/offbye/article/details/38413759

智能推荐

编写一段网页文字放大动画-程序员宅基地

文章浏览阅读70次。如果要在网页上实现文字放大动画,可以使用 CSS 动画或 JavaScript 动画。使用 CSS 动画,可以通过设置 transition 属性来实现动画效果,例如:.text { transition: transform 0.5s; /* 设置动画时间为 0.5 秒 */}.text:hover { transform: scale(1.2); /* 鼠标悬浮时文字放大..._css 动画设置字体变大动画

在fluent计算时如何设置非稳态时的时间步长_fluent时间步长设置-程序员宅基地

文章浏览阅读1.8w次,点赞2次,收藏12次。1、先测出沿流向最小的网格长度2、用该网格长度除以你的进口速度,这就是非稳态的时间步长,能够较好的表现流动特征,特别在计算升力、阻力系数时,能够使你的数据与实验对比较好!_fluent时间步长设置

Linux常用命令——su命令_linux su命令-程序员宅基地

文章浏览阅读819次。用于切换当前用户身份到其他用户身份,变更时须输入所要变更的用户帐号与密码。用于切换当前用户身份到其他用户身份。用户:指定要切换身份的目标用户。变更帐号为root并传入。su(选项)(参数)_linux su命令

ubuntu 编译 jdk (三)_langtools: langtools-only-程序员宅基地

文章浏览阅读2.1k次。 root@ubuntu:/home/gap/jdk8u# make WARNING: You have the following ALT_ variables set:ALT_OUTPUTDIR=/home/gap/buildALT_ variables are deprecated and will be ignored. Please clean your envi..._langtools: langtools-only

yolov8超详细从配置环境到训练测试_yolov8环境配置-程序员宅基地

文章浏览阅读9.4k次,点赞13次,收藏120次。超详细,半天让你使用好yolov8代码_yolov8环境配置

oracle sql经典面试题,经典SQL面试题2-程序员宅基地

文章浏览阅读296次。题目:一张名为workersalary的表,要求查询出全部信息,并且salary最高的三个人按升序排列在结果的最开头,其余的人按原有顺序排列。这个sql如何写?解答:(1)题意理解假如原先的表是这样的namesalaryLiuYi2000ChenEr1000ZhangSan5000LiSi4000WangWu8000ZhaoLiu6000SunQi7000ZhouBa3000题目要求变成这样nam..._sql面试必会6题经典oracle必问的面试题

随便推点

机器学习-9 降维算法——PCA降维-程序员宅基地

文章浏览阅读1.5k次,点赞2次,收藏10次。①降维(Dimensionality Reduction,DR)是指采用线性或者非线性的映射方法将高维空间的样本映射到低维空间中。②降维获得低维空间的数据等价表示,实现高维数据的可视化呈现。仅仅需要以方差衡量信息量,不受数据集以外的因素影响。各主成分之间正交,可消除原始数据成分间的相互影响的因素。计算方法简单,主要运算是特征值分解,易于实现。_pca降维

vue页面动态切换_vue 首页 切换动态画面-程序员宅基地

文章浏览阅读2k次。Vue-router结合transition实现app前进后退动画切换效果首先,配置路由并且修改路由配置配置路由的重点是给Router添加一个goBack方法,用于记录路由的前进状态 this.isBack = trueRouter.prototype.goBack = function () {   this.isBack = true  window.history.go(-1..._vue 首页 切换动态画面

Jupyter NoteBook 中使用 cv2.imshow 显示图片_jupyter cv2.imshow-程序员宅基地

文章浏览阅读3.9w次,点赞26次,收藏32次。Jupyter NoteBook 中使用 cv2.imshow 显示图片有两种办法:用 cv2.imshow时加入cv2.destroyAllWindows()用 plt.imshow() 代替 cv2.imshow1. cv2.imshow加入 cv2.destroyAllWindows() 后可以解决 crash 或者图片显示不出来的问题。import cv2%matplot..._jupyter cv2.imshow

android webView使用-程序员宅基地

文章浏览阅读40次。在Android手机中内置了一款高性能webkit内核浏览器,在SDK中封装为一个叫做WebView组件。一、使用WebView1.加入权限 <uses-permission android:name="android.permission.INTERNET" />2.创建一个webView通过布局 <WebView ...

怎么保存python制作的饼图_Scribus中的Python脚本:制作饼图-程序员宅基地

文章浏览阅读581次。Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发。Scribus是一个强大的开源页面布局应用程序,它是由开源社区自2001年开发的程序。据项目网站可知,Scribus是为Linux,FreeBSD,PC-BSD,NetBSD,OpenBSD,Solaris和程序提供 CMYK颜色,专色,ICC颜色管理和PDF创建的程序。该网站还支持应用程序的高级功能,如矢..._python绘制饼图保存本地

计算机科学与导论期末考,《计算机科学导论》期末考试试题-程序员宅基地

文章浏览阅读475次。《计算机科学导论》期末考试试题(B卷)班级:姓名:学号:成绩:一、单项选择题1. 用一个字节表示无符号整数,其最大值是十进制数()。A. 256B. 255C. 127D. 1282. 一个完整的计算机系统应包括()。A. 运算器、控制器和存储器B. 主机和应用程序C. 硬件系统和软件系统D. 主机和外部设备3. 微机中的CPU是指()。A. 内存和运算器B. 输入设备和输出设备C. 存储器和控..._计算机科学导论期末题

推荐文章

热门文章

相关标签