jquerythen的简单介绍
JavaScript中then的作用
总的来说有一个功能,用Angular JS的post方法向后台发送请求,然后后台返回一段数据交个Angular 来进行处理,先看看service部分:
成都创新互联公司专注于企业全网营销推广、网站重做改版、洛江网站定制设计、自适应品牌网站建设、H5技术、商城建设、集团公司官网建设、外贸网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为洛江等各大城市提供网站开发制作服务。
[javascript] view plain copy
fs.services.factory('MonitorService', ['$http', '$q', function ($http, $q) {
return {
queryByYearOrMonth: function (postData) {
var delay = $q.defer();
$http.post(fs.common.baseResourceURL2 + '/api/monitor/uploadQuantity', postData,{})
.success(function (data) {
delay.resolve(data);
}).error(function () {
delay.reject("Can't search uploadQuantity data.");
});
return delay.promise;
}
}
}]);
如果不经过深入测试的话,第一反应是觉得 delay.resolve(data)这句在处理数据,把数据放在delay对象的promise中,因为最后一句是return delay.promise,想当然地认为
delay.promise就是已经处理好的可以交给controller使用的数据,但经过实际测试,发现不是这么回事。
那就来看看delay.promise到底是什么?在浏览器控制台中,以此输出delay.promise中的属性和值,如下:
[javascript] view plain copy
then: function (callback, errback) {
var result = defer();
var wrappedCallback = function(value) {
try {
result.resolve((callback || defaultCallback)(value));
} catch(e) {
exceptionHandler(e);
result.reject(e);
}
};
var wrappedErrback = function(reason) {
try {
result.resolve((errback || defaultErrback)(reason));
} catch(e) {
exceptionHandler(e);
result.reject(e);
}
};
if (pending) {
pending.push([wrappedCallback, wrappedErrback]);
} else {
value.then(wrappedCallback, wrappedErrback);
}
return result.promise;
}
always: function (callback) {
function makePromise(value, resolved) {
var result = defer();
if (resolved) {
result.resolve(value);
} else {
result.reject(value);
}
return result.promise;
}
function handleCallback(value, isResolved) {
var callbackOutput = null;
try {
callbackOutput = (callback ||defaultCallback)();
} catch(e) {
return makePromise(e, false);
}
if (callbackOutput callbackOutput.then) {
return callbackOutput.then(function() {
return makePromise(value, isResolved);
}, function(error) {
return makePromise(error, false);
});
} else {
return makePromise(value, isResolved);
}
}
return this.then(function(value) {
return handleCallback(value, true);
}, function(error) {
return handleCallback(error, false);
});
}
有两个部分,then 和 always,两个都是可执行的方法。
always 这里不作讨论。来看看then ,它有两个参数,callback 和 errback, 第一个用来处理“resolved”和“success”事件;第二个用来处理“rejected”和“failure”事件。
所以,delay.promise不是现成的数据,还不能直接使用。然后来看看这个then怎么使用(主要是如何从中提取出我们需要的后台返回的数据):
[javascript] view plain copy
uploadQuantityLoader(params).then(function(Cquantity){
$scope.quantityMap = Cquantity.quantityMap;
makeGraph();
});
then(fn) 方法中带一个参数,这个参数就是要被执行的函数,并且,这个作为参数的函数本身有一个参数,这个参数就是我们需要的数据,这里是关键,本例中也就是
Cquantity,然后这个Cquantity就可以放在函数里面进行处理了。
怎么使用jquery的then方法
使用jquery的then方法
1.Deferred.then()相当于Deferred.done()、Deferred.fail()、Deferred.progress()的合体,可以同时注册3个状态下的回调函数。
[javascript] view plain copy
function success(data)
{
alert("success data = " + data);
}
function fail(data)
{
alert("fail data = " + data);
}
function progress(data)
{
alert("progress data = " + data);
}
var deferred = $.Deferred();
// 一起注册回调
deferred.then(success, fail, progress);
// 分别注册回调
deferred.done(success);
deferred.fail(fail);
deferred.progress(progress);
deferred.notify("10%");
deferred.resolve("ok");
当然我们也可以像done()一样,多次调用then()注册回调函数。then()虽然可以这么使用,但是实际开发中一般不这么用,因为没有啥必要。JQuery1.8之前,这就是then()方法的作用。
2.Deferred.then()解决多个异步操作之间有依赖的问题,这才是then()真正有意义的场景。JQuery1.8之后,then()取代了过时的pipe()方法。这种场景下,我们需要使用Deferred.then()返回的新Promise对象。上面的第一种使用方式,我们忽略了Deferred.then()的返回值。
[javascript] view plain copy
var deferred = $.Deferred();
// 使用then()注册一个resolved状态的回调函数,并返回一个过滤后的promise
// 返回的filtered已经不是原来的Deferred或者Promise对象了
var filtered = deferred.then(function( value ) {
alert("trigger Deferred filter.value="+value);//5
return value * 2;
});
// 用过滤后的Promise再次注册回调函数
filtered.done(function( value ) {
alert("filtered value=" + value);//10
});
deferred.resolve( 5 );
我们用deferred.then()注册了一个完成状态下的回调函数,这个回调函数得到的值是5;之后用filtered这个新的Promise注册回调函数,这个回调函数中得到的值是10(第一个回调函数的返回结果)。现在我们看下JQuery官方对then的解释:
These filter functions can return a new value to be passed along to the promise's .done() or .fail() callbacks, or they can return another observable object (Deferred, Promise, etc) which will pass its resolved / rejected status and values to the promise's callbacks. If the filter function used is null, or not specified, the promise will be resolved or rejected with the same values as the original.
我们知道deferred.resolve()、deferred.reject()、deferred.notify()可以指定参数值,这个参数会传递给相应状态下的回调函数。如果我们使用的是done()、fail()、progress()注册的回调函数,那么某个状态下的所有回调函数得到的都是相同参数。但是如果我们使用了then()注册回调函数,那么第一回调函数的返回值将作为第二个回调函数的参数,同样的第二个函数的返回值是第三个回调函数的参数。可以对比下面的2段代码,体会下done()和then的差别。
[javascript] view plain copy
var deferred = $.Deferred();
// done()返回的仍然是原来的Deferred对象
var done_ret = deferred.done(function(data){
alert("data="+data);//5
return 2 * data;
});
alert(deferred == done_ret);//true
done_ret.done(function(data){
alert("data="+data);//5
});
deferred.resolve( 5 );
[javascript] view plain copy
var deferred = $.Deferred();
// then()返回的是一个新Promise对象
//then注册的回调函数的返回值将作为这个新Promise的参数
var then_ret = deferred.then(function(data){
alert("data="+data);//5
return 2 * data;
});
alert(then_ret == deferred);//false
then_ret.done(function(data){
alert("data="+data);//10
});
deferred.resolve( 5 );
同样地,Deferred.then也能够实现rejected和pending状态的回调函数过滤。
[javascript] view plain copy
var defer = $.Deferred();
var filtered = defer.then( null, function( value ) {
return value * 3;
});
defer.reject( 6 );
filtered.fail(function( value ) {
alert( "Value is ( 3*6 = ) 18: " + value );
});
下面这段代码可以实现chain tasks,解决异步操作中回调难的问题。
[javascript] view plain copy
var defered = $.Deferred();
var promise1 = defered.then(function(data){
alert(data);//
return data+="1";
});
var promise2 = promise1.then(function(data){
alert(data);//1
return data+="2";
});
var promise3 = promise2.then(function(data){
alert(data);//12
return data+="3";
});
promise3.done(function(data){
alert(data);//123
});
defered.resolve("");
正是由于then()这个特性,我们就可以上面复杂的AJAX嵌套改成如下形式:
[javascript] view plain copy
var promise1 = $.ajax(url1);
var promise2 = promise1.then(function(data){
return $.ajax(url2, { "data": data });
});
var promise3 = promise2.then(function(data){
return $.ajax(url3, { "data": data });
});
promise3.done(function(data){
// data retrieved from url3
});
jquery when then方法
jQuery.when(deferreds)
参数deferreds,一个或多个延时对象或JS对象,我们初略的认为它就是一个或多个异步请求。
例如:$.when($.ajax("page1.php"), $.ajax("page2.php"))
when()函数常常和done()函数、fail()函数、then()函数联合使用:
done(Function func) - 当deferreds中的处理都完成的时候执行Function回调函数
fail(Function func) - 当deferreds中有一个处理失败的时候执行Function回调函数
then(Function func1,Function func2)- 结合了done和fail函数,当都成功执行func1,当有一个失败执行func2
var whenResult = $.when($.ajax("page1.php"), $.ajax("page2.php"));
whenResult.done(function(a1,a2){
//函数内容略
//a1和a2俩参数是when函数中两个ajax请求的相关jqXHR对象
});
whenResult.fail(function(){
//函数内容略
})
whenResult.then(successFunc,failureFunc);
如果没有参数传递给 jQuery.when(),它会返回一个resolved状态的Promise。
如果向 jQuery.when() 传入一个单独的延迟对象,那么会返回它的 Promise 对象(延迟方法的一个子集)。可以继续绑定 Promise 对象的其它方法,例如, defered.then 。当延迟对象已经被解决(resolved)或被拒绝(rejected)(通常是由创建延迟对象的最初代码执行的),那么就会调用适当的回调函数。例如,由 jQuery.ajax() 返回的 jqXHR 对象是一并立的延迟对象并且可以像下面这样使用:
$.when( $.ajax("test.aspx") ).then(function(data, textStatus, jqXHR){
alert( jqXHR.status ); // alerts 200
});
在多延迟情况下,如果Deferreds延迟对象一被拒绝(rejected),jQuery.when()触发立即调用 “宿主” Deferred(延迟)对象的 failCallbacks。请注意在这个时间点上,有一些延迟对象仍然可以是未解决(unresolved)的。 传递给failCallbacks的参数匹配Deferred(延迟)对象的 failCallbacks被 rejected 拒绝的顺序。那么,在这种情况下,如果需要执行一些额外的处理,例如,取消所有未完成的 ajax 请求,你可以在闭包中进行保持 jqXHR 对象的引用,并且在 failCallback 中检查或取消它们。
例子:
Example: 执行Ajax请求后两个函数是成功的。
$.when($.ajax("/page1.php"), $.ajax("/page2.php")).done(function(a1, a2){
/* a1 and a2 are arguments resolved for the page1 and page2 ajax requests, respectively */
var jqXHR = a1[2]; /* arguments are [ "success", statusText, jqXHR ] */
if ( /Whip It/.test(jqXHR.responseText) ) {
alert("First page has 'Whip It' somewhere.");
}
});
Example: 执行函数myFunc当两个Ajax请求是成功的,如果任一或myFailure有一个错误。
$.when($.ajax("/page1.php"), $.ajax("/page2.php"))
.then(myFunc, myFailure);
文章题目:jquerythen的简单介绍
本文路径:http://ybzwz.com/article/dsdsico.html