15 内置服务2

内置服务2

$http

$http是对Ajax(XHR)的封装。

使用:$http(config);

$http({method: 'GET', url: '/someUrl'}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// 请求成功执行代码
}, function errorCallback(response) {
// 请求失败执行代码
});

参数config是个对象,包含下面这些属性:

  • method:字符串,请求方法。
  • url:字符串,请求地址。
  • params:字符串或者对象,将使用paramserializer序列化并且作为GET请求的参数。
  • data:字符串或者对象,作为请求信息数据的数据。
  • headers:对象,字符串或者函数返回表示发送到服务器的HTTP请求头。如果函数的返回值为空,则headers不发送。函数接受一个配置对象作为参数。
  • xsrfHeaderName:字符串,填充XSRF令牌的HTTP请求头名称。
  • xsrfCookieName:字符串,含有XSRF令牌cookie的名字。
  • transformRequest:函数/函数的数组。转换函数或者一个包含转换函数的数组。转换函数获取http请求体和请求头,并且返回他们的转换版(通常是序列化)。
  • transformResponse:函数/函数的数组。转换函数或者一个包含转换函数的数组。转换函数获取http响应体和响应头,并且返回他们的转换版(通常是序列化)。
  • paramSerializer:字符串或者返回字符串的函数。用于编写请求参数(指定为对象)的字符串表示形式的函数。如果指令是字符串,那么将被解释为通过$injector注册的函数,这意味着你能通过注册服务方式创建你自己的序列化程序。默认的序列化是$httpParamSerializer;或者你可以使用$httpParamSerializerJQLike
  • cache:boolean,如果为true,一个默认的$http缓存将被作为请求的缓存,否则如果存在一个用$cacheFactory创建的缓存实例,则将用于缓存。
  • timeout:数值,毫秒,超时则让请求中止。
  • withCredentials:boolean,是否设置withcredentials flag的XHR对象。查看更多信息的凭据。
  • responseType:字符串,响应头类型。

返回一个HttpPromise对象,包含以下属性:

  • data:字符串或对象。变换函数变换后的响应体。
  • status:数值,响应的http状态码。
  • headers:函数,响应头的getter函数。
  • config:对象,用于生成请求的配置对象。
  • statusText:字符串,响应的HTTP状态文本。

返回对象带有一个标准的then方法和两个特殊的success和error方法。

快捷方法:

  • get(url,[config]);
  • delete(url,[donfig]);
  • head(url,[config]);
  • jsonp(url,[config]);
  • post(url,data,[config]);
  • put(url,data,[config]);
  • patch(url,data,[config]);

因为同源策略的存在,Ajax脚本不能跨域访问资源,所以我们只能把回调函数作为参数之一传给服务器,让服务器端返回数据的时候指定调用我们的回调函数。所以,我们只需要把回调函数写好就可以了,在这里,我们写在success中:

// 在jsonp中,url的最后必须严格带上“&callback=JSON_CALLBACK”,而且名字不能改
var url =
"http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1&callback=JSON_CALLBACK";
$http.jsonp(url)
.success(function (data) { // 在这里定义JSON_CALLBACK。其实与GET差不多
console.log('jsonp:', data)
})
.error(function (err) {
console.log('error', err);
});

属性:

pendingRequests:当前正在等待的请求的配置对象数组。主要是为了用于调试目的。
defaults:请求头配置默认属性。
$httpParamSerializerJQLike:Http参数序列化程序。序列化程序也将按字母顺序排序的参数。

$httpParamSerializerJQLike使用示例:

(function () {
angular.module("Demo", [])
.controller("testCtrl",["$http", "$httpParamSerializerJQLike",testCtrl]);
function testCtrl($http, $httpParamSerializerJQLike){
var data = { id: 1, value: "hello" };//
$http({ method: "post", data: data,//Form Data = {"id":1,"value":"hello"} url: "/url", headers: { "Content-Type": "application/x-www-form-urlencoded" } }).success(function (d) { console.log(d); }).error(function(error){console.log(error);}); $http({ method: "post", data: $httpParamSerializerJQLike(data),//Form Data 变成 id:1 value:hello url: "/url", headers: { "Content-Type": "application/x-www-form-urlencoded" } }).success(function(d){ console.log(d);}).error(function(error){ console.log(error);}); }; }());

设置HTTP请求头:

$http服务将会给所有请求自动创建HTTP头。这个默认设置能完全的通过访问$httpProvider.defaults.headers配置对象配置。目前包含默认配置:

$httpProvider.defaults.headers.common
//-- Accept:application/json,text/plain
$httpProvider.defaults.headers.post
//-- Content-Type:application/json
$httpProvider.defaults.headers.put
//-- Content-Type:application/json

添加或删除这些配置对象的属性:

(1)全局配置:

$httpProvider.defaults.headers.post = {“my-header”:”value”}
(2)单请求配置:

$http({
method:”POST”,
url:”url”,
headers:{
“Content-Type”:” // your config”
},
data:{ data: ” // your data” }
})

重写每个请求的默认转换

下面的代码演示添加一个新的响应转换,在运行后的默认响应转换。

function appendTransform(defaults,transform){
defaults:angular.isArray(defaults)?defaults:[defaults];
return defaults.concat(transform);
}
$http({
url:”url”,
method:”GET”,
transformResponse:appendTransform($http.defaults.transformResponse,function(){
return doTransform(value);
})
})

设置http请求缓存
$http.defaults.cache = true/false;

请求拦截

angular.module(“xxx”,[])
.config([“$httpProvider”,function($httpProvider){
$httpProvider.interceptors.push(“yourInterceptors”);
}])
.factory(“yourInterceptors”,[“$q”,”dependency”, function($q,dependency){
return {
“request”:function(config){
// do something on success
return config;
},
“requestError”:function(rejection){
// do something on error
If(canRecover(rejection)){
return responseOrNewPromise
}
return $q.reject(rejection);
},
“response”:function(response){
// do something on success
return response;
},
“responseError”:function(rejection){
// do something on error
If(canRecover(rejection)){
return responseOrNewPromise
}
return $q.reject(rejection);
}
};
}]);

$q

一个帮助处理异步执行函数的服务。当他们做完处理时,使用它们的返回值(或异常)。

受 Kris Kowa’s Q 的启发,这是一个实现promise/deferred对象的启用。

1、Deferred Api

一个被$q.defer()调用的deferred的新实例。

deferred对象的目的是暴露相关promise实例,以及APIs被执行的成功或不成功情况,以及任务的状态。

方法:

  • resolve(value):根据value以解决派生的promise。如果值是通过$q.reject构造的rejection 对象,该promise将被拒绝。
  • reject(reason):根据reason以拒绝派生的promise。这相当通过 $q.reject构造的rejection 对象来解决。
  • notify(value):在 promise 被执行的过程中提供状态更新情况。这可能会被多次调用,在promise是被解决还是被拒绝之前。

属性:

  • promise:{Promise},与这个deferred相关的promise对象。

2、Promise Api

当一个deferred实例被创建时,一个promise实例被创建,并且可以通过调用deferred.promise检索。Promise对象的目的是当它完成后允许需要的地方获得deferred任务的结果。

方法:

  • then(successCallback,errorCallback,notifyCallback);

无论什么时候,promise是已经(将要)被解决或拒绝,只要结果是可用的,就调用一个成功/错误的回调异步。回调函数带着一个参数被调用:解决的结果或拒绝的原因。此外,在承诺被解决或被拒绝之前,通知回调可能被调用0或多次用来提供一个指示进度。
这个方法返回被successCallback/errorCallback的解决或拒绝的返回值作为一个新的承诺(除非返回值是个promise,在承诺链的承诺和值都被解决的情况下)。它还将通过notifycallback方法的返回值进行通知。promise 不能从notifyCallback方法得到解决或拒绝 。

  • catch(errorCallback);

promise.then(null, errorCallback) 的快捷方式。
* finally(callback,notifyCallback);
允许你观察一个承诺的解决或拒绝,但这样做不能修改最后的值。这可用于promise不论是被解决或拒绝后释放资源或做一些清理。
链式承诺

因为调用本次promise的方法将会返回一个新的延生的promise,它很容易创建一个承诺链:

promise = promise.then(function(result){ return result+1; });
当一个promise解决另一个promise(这将推迟其进一步的解决)可能创建一个任何长度的链。它可能在链中的任何处暂停/推迟promise。这使得它可以像$http的响应拦截这类强大的API。

Kris Kowal’s Q和$q的两个主要的不同

1、在Angular里, q rootScope.Scope Scope模型的观察机制集成,这意味着更快的将解决/拒绝的结果传播到你的model和避免不必要的浏览器重新渲染(这将导致ui的闪烁)。

2、Q比 q q是小版本的,但包含所有常见的异步任务所重要的功能。

$q的使用:$q(resolver);

方法:

  • defer();
    创建一个deferred对象,它代表一个将在将来完成的任务。返回一个deferred的新实例。
  • reject(reason);
    创建一个由指定的理由拒绝的promise。在承诺链中,这个api将被用于promise的拒绝。如果你正在处理一个承诺链的最后一个promise,那么你不需要担心它。
    reason:常数,消息,异常或一个对象,表示拒绝原因。
    返回一个已经根据拒绝原因解决了的promise。
  • when(value);
    将一个对象或者一个值或者一个第三方承诺包装进$q承诺。当你处理一个可能是承诺或可能不是承诺或承诺来自一个不可信的来源的对象。
    value:值或者承诺。
    返回一个承诺。
  • resolve(value); when的别名,为了与ES6保持一致。
  • all(promises);
    当所有承诺都得到解决后,在一个单一的承诺里集合多个被解决的承诺。
    promises:承诺的数组或者哈希。
    返回一个将被结合一个数组/哈希或者值解决的单一的承诺,每个值在相同索引/键的数组/哈希承诺对应相对承诺,如果有任何承诺被拒绝,这将导致承诺被以相同的拒绝值拒绝。

使用示例:

(function () {
angular.module('Demo', [])
.controller('testCtrl', ["$q", testCtrl]);
function testCtrl($q) {
var fn = function (value) {
var defer = $q.defer();
if (value == "Hello") {
defer.resolve("Hello World");
} else {
defer.reject("hello world");
}
return defer.promise;
};
var promise = fn("Hello");
promise.then(function (v) {
console.log("resolved with " + v);
}, function (r) {
console.log("rejected with " + r);
});//Hello World
var anotherPromise = fn();
anotherPromise.then(function (v) {
console.log("resolved with " + v);
}, function (r) {
console.log("rejected with " + r);
});//hello world
}
}());

承诺链:

(function () {
angular.module('Demo', [])
.controller('testCtrl', ["$q", testCtrl]);
function testCtrl($q) {
var fnA = function (value) {
var defer = $q.defer();
if (value == "Hello") {
defer.resolve("Hello World -- fnA");
} else {
defer.reject("hello world -- fnA");
}
return defer.promise;
};
var fnB = function (value) {
var defer = $q.defer();
if (value == "Hello") {
defer.resolve("Hello World -- fnB");
} else {
defer.reject("hello world -- fnB");
}
return defer.promise;
};
var promise = fnA("Hello");
promise.then(function (v) {
console.log("resolved with " + v);//Hello World -- fnA
return fnB();
}, function (r) {
console.log("rejected with " + r);
return fnB("Hello");
}).then(function (v) {
console.log("resolved with " + v);
}, function (r) {
console.log("rejected with " + r);//hello world -- fnB
})
}
}());

.when():

(function () {
angular.module('Demo', [])
.controller('testCtrl', ["$q", testCtrl]);
function testCtrl($q) {
var obj = { value: "Hello World" };
$q.when(obj.value).then(function (v) { console.log(v);// Hello World obj = { text: "hello world" } return $q.when(obj.text); }).then(function (v) { console.log(v);// hello world })
}
}());

.all():

(function () {
angular.module('Demo', [])
.controller('testCtrl', ["$q", testCtrl]);
function testCtrl($q) {
var fnA = function (value) {
var defer = $q.defer();
if (value == "Hello") {
defer.resolve("Hello World -- fnA");
} else {
defer.reject("hello world -- fnA");
}
return defer.promise;
};
var fnB = function (value) {
var defer = $q.defer();
if (value == "Hello") {
defer.resolve("Hello World -- fnB");
} else {
defer.reject("hello world -- fnB");
}
return defer.promise;
};
var promiseA = fnA("Hello").then(function (v) {
console.log("resolved with " + v);
return fnB();
}, function (r) {
console.log("rejected with " + r);
return fnB("Hello");
});
var promiseB = fnB().then(function (v) {
console.log("resolved with " + v);
}, function (r) {
console.log("rejected with " + r);
});
var promises = [promiseA, promiseB];
$q.all(promises);
/* result:
** resolved with Hello World -- fnA
** rejected with hello world -- fnB
*/
}
}());

猜你喜欢

转载自blog.csdn.net/Fighting_No1/article/details/80036480
15