angularJS中XHR与promise
angularJS应用是完全运行在客户端的应用,我们可以通过angularJS构建一个不需依赖于后端,同时能够实现动态内容和响应的web应用,angularJS提供了将应用与远程服务器的信息集成在一起的方法
$http服务
- angularJS提供了内置的$http服务直接同外部进行通信,$http服务封装了浏览器原生的XMLHttpRequest对象
$http服务只接收一个参数对象,包含了用来生成http请求的配置内容,$http函数返回一个promise对象,具有success和error两个方法,也可以通过then()处理回调
//示例:
$http( {
url : '/api/user.php',
method : 'post',
data : { id : 486 }
} ).success( function(data,status){
//当请求响应成功后调用
} ).error( function(data,status){
//当请求响应错误后调用
} ); $http( {
url : '/api/user.php',
method : 'post',
data : { id : 486 }
} ).then( function(data){
//当请求响应成功后调用
}, function(error){
//当请求响应错误后调用
} );
$http参数详解
method(字符串)
指令发送http请求的方式,值有get、post、jsonp、head、delete、put
url(字符串)
请求的目标地址,绝对或相对URL
params(字符串map或对象)
这个键的值是一个字符串map或对象,会被转换成查询字符串追加在URL后面
data(字符串或对象)
这个键的值包含了将要被当作消息体发送给服务器的数据,通常在发送post请求时使用
cache(布尔型或缓存对象)
如果cache属性被设置为true,那么angularJS会用默认的$http缓存来对get请求进行缓存,
如果cache属性被设置为一个$cacheFactory对象的实例,那么这个实例会被用来对get请求进行缓存responseType(字符串)
responseType选项会在请求中设置XMLHttpRequestResponseType属性,指定返回数据类型,
如下可以指定的类型document(http文档)、text(字符串)、json(从json对象解析而来的json字符串)等timeout(数值型或promise对象)
如果timeout被设置为数值,那么请求将会在超时timeout指定的毫秒数后再发送,
如果被设置为一个promise对象,当该promise对象被resolve时请求被终止headers
随请求发送的http头,如headers: {'Content-Type': 'application/x-www-form-urlencoded'}
$http快捷方法
- $http.get( url, config );
- $http.post( url , data , config )
$http.jsonp( url, config )
//为了发送jsonp请求,url地址上必须包含JSON_CALLBACK字样
$http.jsonp('./api/user.php?callback=JSON_CALLBACK',config).success( function(){ } ).error( function(){ } );$http.put( url, data, config )
$http.delete( url, config )
$http.head( url, config )
缓存http请求
默认$http服务不会对请求进行本地缓存,在发送单独请求时,我们可以向$http的cache配置项传入一个布尔值或缓存实例来启用缓存
//示例:
$http.get('./api/user.php',{cache : true}).success( function( data ){ } ).error( function(data){ } ); /*创建一个$cahceFactory对象实例*/
var cacheInstance = $cacheFactory( 'cacheInstance',{
capacity : 20 //最新的20个请求被缓存
} ); $http.get('./api/user.php',{cache : cacheInstance }).success( function( data ){ } ).error( function(data){ } ); //如果要给全局的$http配置缓存,可以通过应用的config()函数给所有$http请求设置一个默认的缓存:
angular.module('freefedService',[]).config( ['$httpProvider','$cacheFactory',function($httpProvider,$cacheFactory){
$httpProvider.defaults.cache = $cacheFactory('cacheInstance',{
capacity : 20
})
}] );
拦截器
- angularJS通过拦截器提供了一个从全局层面对响应进行处理的途径,使用场景:如身份验证、错误处理等
- 拦截器的核心是服务工厂,通过向$httpProvider.interceptors数组中添加服务工厂,在$httpProvider进行注册
拦截器有request、response、requestError、responseError四种
request
angularJS通过$http设置对象对请求拦截器进行调用,
它可以对设置对象进行修改,或者创建一个新的设置对象,
她需要返回一个更新过的设置对象,或者一个可以返回新的设置对象的promiseresponse
angularJS通过$http设置对象对响应拦截器进行调用,
它可以对响应进行修改,或者创建一个新的响应,
她需要返回一个更新过的响应,或者一个可以返回新响应的promiserequestError
angularJS会在上一个请求拦截器抛出错误,或者promise被reject时调用此拦截器
responseError
angularJS会在上一个响应拦截器抛出错误,或者promise被reject时调用此拦截器
设置拦截器
/*创建拦截器*/
angular.module('freefedService',[]).factory('httpInterceptor',['$q',function( $q ){
return {
request : function( config ){
if (config.method.toLocaleLowerCase() == 'post') {
config.headers['X-CSRFToken'] = 'unbu12lk9';
}
return config;
},
response : function( response ){
return response;
},
requestError : function( rejection ){ return $q.reject(rejection); },
responseError : function( rejection ){
if( rejection.status >400 ){ }
return $q.reject(rejection);
}
};
}]); /*注册拦截器*/
angular.module('freefedApp',['freefedService']).config(['$httpProvider',function($httpProvider){
httpProvider.interceptors.push( 'httpInterceptor' );
}]);
promise
什么是promise
promise是抽象异步处理对象以及对其进行各种操作的组件
为什么使用promise
习惯上,javascript使用闭包或者回调来响应非同步的数据,比如页面全完加载完后,发起获取用户信息的xhr请求,我们可以直接在回调函数中的跟返回的数据进行交互, 而不用关心它什么时候被触发,但是使用回调的痛点也暴露了很多:
- 回调使得调用不一致得不到保证
- 当依赖其他回调时,它们篡改代码流程,让代码逻辑复杂,调试变的困难
使用promise带来的改变:
- 逃脱了回调地狱,promise让异步函数看起来像同步的
可以按照预期来捕获返回值和异常值
ES6 Promise 示例:
var xhrFunc = function( options ){
var options = options || {};
var method = 'options.method' || 'get';
var url = options.url || '';
return new Promise( function( resolve, reject ){ //创建promise对象并返回
var xhr = new XMLHttpRequest();
xhr.open(method,url);
xhr.onload = function(){
if( xhr.status == 200 ){
/*请求成功后,通过resolve()传入数据参数,then 方法对应的成功处理函数可以接收到这个参数值*/
resolve( xhr.responseText );
}else{
/*请求出错,通过reject()传入错误信息,then 方法对应的处理错误的函数可以接收到这个错误信息**/
reject( new Error( xhr.statusText ) );
}
};
xhr.onerror = function(){
reject( new Error( xhr.statusText ) );
}; xhr.send();
});
}; xhrFunc( { url : './api/user.php' } ).then( function onFulfilled( data ){
/*promise对象被 resolve 时的处理(onFulfilled)*/
console.log( data );
}, function onRejected( error ){
/*promise对象被 reject 时的处理(onRejected)*/
console.log( error );
} );
angular中的promise
- 如何创建angularJS中的promise 通过使用内置的$q服务,$q在它的deferred API中提供了一些方法,通过创建一个deferred对象,deferred对象暴露三个方法和一个可以处理promise的promise属性:
resolve( value )
resolve函数用这个value值来执行deferred promise
reject( reason )
reject函数用一个原因来拒绝dererred promise,它等于使用一个拒绝来执行一个promise
notify( value )
用promise的执行状态来进行响应,
如我们要从promise返回一个状态进度,可以使用notify()函数来传送它promise
var deferred = $q.defer(); //调用$q服务的defer方法创建一个defer对象
deferred.promise //通过访问promise属性得到promise对象
promise中方法
then(successFn,errFn,notifyFn)
无论promise成功还是失败了,当结果可用之后,
then都会立刻异步调用successFn或者errFn,
在promise被执行或拒绝之前,notifyFn回调可能会被调用0到多次,以提供过程状态的提示catch( errFn );
可以通过catch捕获错误,替代then中的errFn
示例代码:
demo.html <!doctype html>
<html ng-app="freefedApp">
<head>
<title>angular应用demo</title>
<script src="angular.js"></script>
<script src="service.js"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="userCtrl">
<div class="user-center">
<span class="user-icon"><img src="{{vm.user.pic}}" /></span>
<span class="user-name">{{vm.user.name}}</span>
</div>
</div>
</body>
</html>
//service.js angular.module('freefedService',[]).factory('ajaxService',['$http','$q',function($http,$q){
var deferred = $q.defer();
return function(params){
var params = params || {};
$http({
method : params.method || 'post',
url : params.url || '',
data : params. data || {},
responseType : params.type || 'json'
}).success(function(data){
deferred.resolve(data);
}).error(function(reason){
deferred.reject(reason);
});
return deferred.promise()
};
}]); //app.js /*声明module*/
var module = angular.module('freefedApp',['freefedService']); /*声明控制器*/
module.controller('userCtrl',['$scope','ajaxService',function($scope,ajaxService){
var vm = $scope.vm = $scope.vm || {};
vm.user = {};
//调用ajaxService服务
ajaxService( {
url : '/getUser.php'
} ).then(function(data){
vm.user.pic= data.pic;
vm.user.name = data.name;
},function(error){
alert( error.msg );
}
);
}]);
angularJS中XHR与promise的更多相关文章
- AngularJS学习--- AngularJS中XHR(AJAX)和依赖注入(DI) step5
前言:本文接前一篇文章,主要介绍什么是XHR,AJAX,DI,angularjs中如何使用XHR和DI. 1.切换工具目录 git checkout -f step- #切换分支 npm start ...
- AngularJS 中的Promise --- $q服务详解
先说说什么是Promise,什么是$q吧.Promise是一种异步处理模式,有很多的实现方式,比如著名的Kris Kwal's Q还有JQuery的Deffered. 什么是Promise 以前了解过 ...
- angularJS中的Promise对象($q)的深入理解
原文链接:a better way to learn AngularJS - promises AngularJS通过内置的$q服务提供Promise编程模式.通过将异步函数注册到promise对象, ...
- Angularjs中的promise
promise 是一种用异步方式处理值的方法,promise是对象,代表了一个函数最终可能的返回值或抛出的异常.在与远程对象打交道非常有用,可以把它们看成一个远程对象的代理. 要在Angular中创建 ...
- AngularJS 中的 Promise 和 设计模式(转)
原文地址:http://my.oschina.net/ilivebox/blog/293771 目录[-] Promise 简单例子 链式 Promise Parallel Promises And ...
- AngularJS 中的 Promise 和 设计模式
解决 Javascript 异步事件的传统方式是回调函数:调用一个方法,然后给它一个函数引用,当这个方法完结的时候执行这个函数引用. <!-- lang: js --> $.get('ap ...
- AngularJS中处理多个promise
在使用AngularJS中处理promise的时候,有时会碰到需要处理多个promise的情况. 最简单的处理就是每个promise都then.如下: var app = angular.module ...
- AngularJS中实现无限级联动菜单(使用demo)
昨天没来得及贴几个使用demo,今天补上,供有兴趣的同学参考 :) 1. 同步加载子选项demo2. 异步加载子选项demo3. 初始值回填demo4. 倒金字塔依赖demo directive的源代 ...
- AngularJS中实现无限级联动菜单
多级联动菜单是常见的前端组件,比如省份-城市联动.高校-学院-专业联动等等.场景虽然常见,但仔细分析起来要实现一个通用的无限分级联动菜单却不一定像想象的那么简单.比如,我们需要考虑子菜单的加载是同步的 ...
随机推荐
- Jenkins 十一: 构建Maven项目
1. 点击“新建”,在“Item名称”栏输入要构建的项目名,比如“Maven_project”,选择“构建一个maven项目”,点击“OK”按钮. 2. 找到“源码管理”-> “Subversi ...
- kafka Disks and Filesystem(磁盘和文件系统)
转载请注明来源地址:http://www.cnblogs.com/dongxiao-yang/p/5206631.html We recommend using multiple drives to ...
- ubuntu vim YouComlpeteMe配置
使用vundle安装时,在.vimrc中添加 Plugin 'Valloric/YouCompleteMe' 使用Bundle会安装失败原因未知 YCM编译时附加选项--system-libclang ...
- [转] 关于c++的头文件依赖
http://www.cnblogs.com/yvesliao/p/3938730.html PS: 使用单向依赖 正在看google c++编程规范,里面对头文件依赖是这么说的: 1 2 3 4 5 ...
- 记录jpcap在Ubuntu&Window下的配置过程
众所周知,Java虽然在TCP/UDP传输方面给予了良好的定义,但是标准库java.net对于网络层以下的控制是无能为力的.Jpcap就是为了处理这一问题而出现的中间件.它调用底层的winpcap/l ...
- TCP/IP协议原理与应用笔记11:TCP/IP中地址与层次关系
1. 网络中常用的地址: 2. TCP/IP中地址与层次关系 :
- uva 1391 Astronauts(2-SAT)
/*翻译好题意 n个变量 不超过m*2句话*/ #include<iostream> #include<cstdio> #include<cstring> #inc ...
- NPOI从数据库中导出数据到Excel
首先要添加NPOI.dll程序集 https://yunpan.cn/cMeSTELJSXmJJ 访问密码 8d83 把里面的程序集都添加到引用里 下面的代码是从数据库导出到Excel { //pa ...
- win10的独立存储
win10的独立存储和win8的大致相同 Windows.Storage.ApplicationDataContainer roamingSettings = Windows.Storage.Appl ...
- 学习CSS一些事(上)
p.s:这是我在学习中总结出来知识,如有不对,请多包涵.谢谢. CSS样式:行内样式,内部样式,外部样式,他们的优先级是:行内,内部,外部,遵循就近原则. 一.HTML+CSS布局分为三大类,一是流式 ...