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(
);

 }]);

 
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
errFn asynchronously 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.
 
 

Promise in AngularJS的更多相关文章

  1. angularJS中XHR与promise

    angularJS应用是完全运行在客户端的应用,我们可以通过angularJS构建一个不需依赖于后端,同时能够实现动态内容和响应的web应用,angularJS提供了将应用与远程服务器的信息集成在一起 ...

  2. angularJS笔记之Promise

    Promise是一种模式,以同步操作的流程形式来操作异步事件,避免了层层嵌套,可以链式操作异步事件. 我们知道,在编写javascript异步代码时,callback是最最简单的机制,可是用这种机制的 ...

  3. 以todomvc为例分析knockout、backbone和angularjs

    一.整体结构 项目github地址https://github.com/tastejs/todomvc/ 排除通用的css样式文件和引用的js库文件,仅看html和js 1.1 knockoutjs版 ...

  4. AngularJS(Part 10)--页面导航

    页面导航     过去,一个URL代表一个页面.但是随着Ajax的兴起,情况发生的很大的变化.不同的内容可以使用同一个URL.这让浏览器中的回退.前进甚至收藏按钮都失去了作用.而AngularJS提供 ...

  5. amgular $q用法

    amgular $q用法   在用JQuery的时候就知道 promise 是 Js异步编程模式的一种模式,但是不是很明白他跟JQuery的deferred对象有什么区别.随着公司项目的进行,要跟后台 ...

  6. Angular简单应用剖析

    这一篇我们将一起感受学习一个小型的.活生生的应用,而不是继续深入分析哪些单个的特性.我们将会一起感受一下,前面所讨论过的所有片段如何才能真正的组合在一起,形成一个真实的.可以运行的应用. GutHub ...

  7. Angular中的$q的形象解释及深入用法

    作者:寸志链接:https://zhuanlan.zhihu.com/p/19622332来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 早上,老爸说:“儿子,天气如何 ...

  8. IT_Qestion

    1. Javascript 回调 Promise 2. Angularjs $parent 3. CSS margin padding border 4. Angularjs $filter 5. D ...

  9. AngularJS 中的Promise --- $q服务详解

    先说说什么是Promise,什么是$q吧.Promise是一种异步处理模式,有很多的实现方式,比如著名的Kris Kwal's Q还有JQuery的Deffered. 什么是Promise 以前了解过 ...

随机推荐

  1. wpf的学习日志(二)

    window演示基础(windows presentation Foundation)用于windowsw图形显示系统 InitializeComponent()方法的工作就是system.windo ...

  2. eclipse打包jar时包含第三方jar包的相关问题

    我用的是mars4.5版本的eclipse 需求:要把写好的工程打成jar包,并能直接运行.工程用了若干个第三方jar. 在打包的时候,eclipse提供的打包方法不能引用第三方jar包,导致了出现C ...

  3. Oracle创建表空间以及用户,并授权

    //创建临时表空间   create temporary tablespace testtemp  tempfile 'D:/app/Administrator/oradata/testdata/te ...

  4. [转] iOS开发- UICollectionView详解+实例

    本章通过先总体介绍UICollectionView及其常用方法,再结合一个实例,了解如何使用UICollectionView. UICollectionView 和 UICollectionViewC ...

  5. XCode的一些调试技巧

    XCode 内置GDB,我们可以在命令行中使用 GDB 命令来调试我们的程序.下面将介绍一些常用的命令以及调试技巧. po 命令:为 print object 的缩写,显示对象的文本描述(显示从对象的 ...

  6. Django 1.10中文文档—第一个Django应用Part1

    在本教程中,我们将引导您完成一个投票应用程序的创建,它包含下面两部分: 一个可以进行投票和查看结果的公开站点: 一个可以进行增删改查的后台admin管理界面: 我们假设你已经安装了Django.您可以 ...

  7. MPICH2在两台Ubuntu上安装(用mpd做进程管理)

    本文在经过大量的实验终于不负众望成功的在两台Ubuntu 12.04上部署MPI的一个小型集群,MPICH2所用版本为mpich2-1.4.1,下载地址:http://www.mcs.anl.gov/ ...

  8. Python的多线程实现

    概述 Python虚拟机使用GIL(Global Interpreter Lock,全局解释器锁)来实现互斥线程对共享资源的访问,暂时无法利用多处理器的优势. Python中,thread和threa ...

  9. Day4 内置函数补充、装饰器

    li = [11,22,33,44]def f1(arg): arg.append(55)#函数默认返回值None,函数参数传递的是引用li = f1(li) print(li)   内置函数补充: ...

  10. python -i filename

    今天学习的时候看见python -i filaname 这个命令,书上说使用这个命令可以去执行filename文件中的代码.但是今天在使用的时候却一直报错,经过多次测试才把问题解决. 原来这个命令是不 ...