您的位置:首页 > Web前端 > AngularJS

AngularJS Promise

2016-07-27 17:04 399 查看
本文参考自AngularJS权威教程。

本文参考了http://www.myext.cn/javascript/a_6436.html

1. 简介

  promise是一种用异步方式处理值的方法。promise是一个对象,代表一个函数可能的返回值或者抛出的异常。在与远程对象打交道时,我们可以简单的把它看作远程对象的一个代理。

  我们通常习惯用回调来相应非同步的数据,但是回调使得调用不一致,当依赖于其他回调时,层次会越来越多,形成一个回调金字塔,通常这会让调试非常困难。

2.工作原理

  promise是一种异步处理机制,其工作原理如下图。



  在promise模式中,defer对象就相当于一个异步执行体,它用resolve()方法返回执行成功的消息,用reject()方法返回执行失败的消息。而promise对象就是一个回调执行体,我们可以在上面操纵接收到成功消息和失败消息分别做什么。

3.$q服务

  $q服务是AngularJS专门为promise异步编程模式而存在的,它有以下几个API。

defer()

获取defer对象。

resolve(value)

向promise对象发送消息,告诉它我已完成任务,value为发送的消息。

reject(value)

向promise对象发送消息,告诉它任务失败,value为发送的消息。

notify(value)

向promise对象发送消息,告诉它目前完成任务的进度,value即为发送的消息。

另外,promise对象即通过defer.promise获取,这两个对象成为一对,协作完成异步执行的任务。下面是promise的API。

then(successCallback,errorCallback,notifyCallback):参数即为不同消息下的不同回调函数,根据defer发送的状态执行相应的回调函数。

catch(errorCallback)

then(null,errorCallback)的一个语法糖,一般放在链式调用的最后处理,如果不把error的信息用console log出来的话,console台是不会报错误的,加上catch并log出错误信息总是一个好习惯。

finally(callback)

then(callback,callback)的语法糖,意思很直观,就是不管你任务成功还是失败都要完成的事情。

4.实例

  首先是一个简单的例子。在这个例子中,我们先是注册了一个自定义服务(XiaoMingService),这个服务调用了$http服务取本地服务器数据并返回该promise。注意,在这个例子中并没有涉及到defer(),因为它由$http完成。(配置本地服务器可用https://github.com/typicode/json-server

<body ng-app="myApp" ng-controller="myController">
<ul>
<li ng-repeat="name in data">
{{ name }}
</li>
</ul>
<script>
var app = angular.module("myApp",['ionic']);
app.factory('XiaoMingService',['$http',function($http) {
return {
getPersonName:function() {
var data = null;
var promise = $http({
method:"GET",
url:"http://localhost:3000/person"
});
return promise;
}
}
}]);
app.controller('myController',function($scope,XiaoMingService) {
$scope.data = [];
var promise = XiaoMingService.getPersonName();
promise.then(function(response) {
$scope.data = response.data;
},function(error) {
console.log(error);
});
});
</script>
</body>


  接下来是关于一个链式调用逃离回调金字塔的例子。假设我们想获得著名国家领导人的列表,于是我们让小李去找数据,小李也不知道怎么获得,于是找小红,小红再找小明,小明找到数据后一层层的返回,小红小李分别在列表加上自己喜欢的领导人。

  我们注册三个Service,分别代表以上三人,同时定义两个复选框,选择是否信任小李和小红来模拟异步获取数据失败的处理,只要不信任小李和小红其中一个人,就不会拿到除了习近平以外的数据,并且演示了finally和catch的用处。

<body ng-app="myApp" >
<div ng-controller="myController">
<ul>
<li ng-repeat="name in data">
{{ name }}
</li>
</ul>
<p>{{ failReason }}</p>
</div>
<p>
信任小红<input type="checkbox" ng-model="trust1"/>
信任小李<input type="checkbox" ng-model="trust2"/>
</p>
<input type="button" value="查询" ng-click="getData()"/>
<script>
var app = angular.module("myApp",['ionic']);
app.factory('XiaoMingService',function($http) {
return {
getPersonName:function() {
var data = null;
var promise = $http({
method:"GET",
url:"http://localhost:3000/person"
});
return promise;
}
}
});
app.factory('XiaoHongService',function($rootScope,$q,$timeout) {
return {
getXiaoHongService:function(data) {
var defer = $q.defer();
\$timeout(function () {
if($rootScope.trust1) {
data.push("李克强");
defer.resolve(data);
}
else {
defer.reject("失败原因:小红不被信任");
}
},2000);
return defer.promise;
}
}
});
app.factory('XiaoLiService',function($rootScope,$q,$timeout) {
return {
getXiaoLiService:function(data) {
var defer = $q.defer();
\$timeout(function () {
if($rootScope.trust2) {
data.push("奥巴马");
defer.resolve(data);
}
else {
defer.reject("失败原因:小李不被信任");
}
},2000);
return defer.promise;
}
}
});
app.controller('myController',function($scope,$rootScope,XiaoMingService,XiaoHongService,XiaoLiService) {
$scope.data = [];
$rootScope.trust1 = true;
$rootScope.trust2 = true;
$scope.failReason = "";
$rootScope.getData = function() {
var promise = XiaoMingService.getPersonName();
promise
.then(function(response){
return XiaoHongService.getXiaoHongService(response.data);
})
.then(function(data) {
return XiaoLiService.getXiaoLiService(data);
})
.then(function (data) {
$scope.data = data;
})
.finally(function(data) {
$scope.data.push("习近平");
})
.catch(function(error) {
$scope.failReason = error;
});
};
});
</script>
</body>




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: