JS的常规请求方式是同步的,这样容易造成阻塞,而后来改进引入了ajax来处理异步请求,同样是对XMLHTTPRequest的封装,angularjs也提供了异步处理机制。怎样理解异步请求呢?
现在寒冬将至,我需要一套被子,以度过寒冬。于是我向被服店发起一个请求,那就是替我定制一套被服。当然定制的话需要一定的时间来生产,我并不着急,放下定金我就走了,并告诉店主,做好了给我送过去,并留下地址和联系方式。那么我就可以去做其他的事情,我不可能因为这点事情而耽误生活继续。这就是简单的我发起了一个异步请求,也可以称为可延期的请求。但是我不会无限期的等待,所以我需要跟店主确认需要多长时间来处理这个事情,显然我不可能等过整个寒冬,那这个被子对我来说将毫无意义。所以我需要店主的一个承诺,一个promise。店主将承诺时间告诉我这就叫做$q.defer延期请求,并可以通过某种回执来时刻关注进展情况。这种就叫做deferred,延期事件。
在这个请求的过程中,我们可以想到有很多的情况,比如,由于机器损坏或者被子的原料不够,需要从外地进货,不能按期完成,那么在处理这个请求的过程中,店主就可以发起reject回执,从而来减少我的等待,你做不了,我就需要得到一个回执,然后我需要找其他的店铺来处理这种事情。当然这种reject不单单包含回执消息还可以包含其他的东西,你比如定金回退,违约金回退,以及原因等消息。如果这个请求事件一直进行的比较顺利,店家又比较贴心,那么他会实时或者每天,每周给我发个消息,来汇报被子的进展情况,这就叫通知notify。最后,店家如期的将被子做好,送到我住的地方,我给他个好评,整个请求的过程完满结束,那就是处理完成了,我们称为resolve。
从上面我们可以看到,一次异步请求应当包含但不仅包含这三个方面。看一下如何来使用这种异步方式。
1.$http
$http({
method:'GET',
url:'api/ham/guest/account/getAccountList'
});
看起来跟ajax的很相似,那么他本身是个什么东西呢?我们来打印一下:
var promise = $http({
method:'GET',
url:'api/ham/guest/account/getAccountList'
});
console.log("promise",promise);
var promise = $http({
method:'GET',
url:'api/ham/guest/account/getAccountList'
});
promise.success(function (data) {
console.log("data",data);
});
promise.then(function (data) {
console.log("success",data)
});
promise.error(function (data) {
console.log("error",data)
})
我们看一下打印结果,从这里面我们可以明显看出,success中的数据就是我们想要的服务端返回的数据,而在then中我们发现他不但包含了我们的服务端的数据,还包含状态码以及header部分,当然由于状态码是200,说明这次请求是成功了,所以不会打印error中的东西:
2.$q
function getList() {
var deferred = $q.defer();
console.log("deferred",deferred);
$http.get(ovHttp.proxy('api/ham/guest/account/getAccountList'))
.success(function (data, status) {
//if (data.result == 'success') {
deferred.resolve(data);
//}
//else if (data.result != 'success') {
// //handleError();
//}
});
console.log("deferred.promise",deferred.promise);
return deferred.promise;
}
2.1 第一种方式
function testQ(){
return $q(function (resolve, reject) {
$timeout(function () {
if(1==1){
resolve("resolve");
}else{
reject("reject");
}
},1000)
})
}
controller中:
amGuestAccountService.testQ().then(
function (data) {
console.log("success",data);
},
function (data) {
console.log("error",data);
})
.catch(function (data) {
console.log("error",data);
});
function testQ(){
return $q(function (resolve, reject) {
$timeout(function () {
if(1!=1){
resolve("resolve");
}else{
reject("reject");
}
},1000)
})
}
2.2 第二种方式
function getList() {
var deferred = $q.defer();
console.log("deferred",deferred);
$http.get(ovHttp.proxy('api/ham/guest/account/getAccountList'))
.success(function (data, status) {
deferred.resolve(data);
}, function (data,status) {
deferred.reject("reject the request");
});
return deferred.promise;
}
amGuestAccountService.getList().then(function (data) {
console.log("resolve",data);
}, function (data) {
console.log("reject",data)
}, function (data) {
console.log("notify",data);
});
2.3 promise的其他方法
function q1() {
var deferred = $q.defer();
$timeout(function () {
deferred.notify("1 notify");
if (1==1) {
deferred.resolve("1 resolved");
} else {
deferred.reject("1 reject");
}
}, 1000);
return deferred.promise;
}
function q2() {
var deferred = $q.defer();
$timeout(function () {
deferred.notify("2 notify");
if (1==1) {
deferred.resolve("2 resolved");
} else {
deferred.reject("2 reject");
}
}, 1000);
return deferred.promise;
}
$q.all([q1(),q2()]).then(function (data) {
console.log("resolve",data);
}, function (data) {
console.log("reject",data)
}, function (data) {
console.log("notify",data);
});
输出结果:
function q1() {
var deferred = $q.defer();
$timeout(function () {
deferred.notify("1 notify");
if (1==1) {
deferred.resolve("1 resolved");
} else {
deferred.reject("1 reject");
}
}, 1000);
return deferred.promise;
}
function q2() {
var deferred = $q.defer();
$timeout(function () {
deferred.notify("2 notify");
if (1!=1) {
deferred.resolve("2 resolved");
} else {
deferred.reject("2 reject");
}
}, 1000);
return deferred.promise;
}
function q3() {
var deferred = $q.defer();
$timeout(function () {
deferred.notify("3 notify");
if (1!=1) {
deferred.resolve("3 resolved");
} else {
deferred.reject("3 reject");
}
}, 1000);
return deferred.promise;
}
function q4() {
var deferred = $q.defer();
$timeout(function () {
deferred.notify("4 notify");
if (1==1) {
deferred.resolve("4 resolved");
} else {
deferred.reject("4 reject");
}
}, 1000);
return deferred.promise;
}
在上面,我定义了四个promise,其中有两个是reject的,那么我们来看看输出结果是怎么样的呢?