@H_301_0@
一、前言
jQuery1.5之前,如果需要多次Ajax操作,我们一般会使用下面的两种方式: @H_301_0@1).串行调用Ajax二、详解
2.什么是deferred对象? deferred对象即延迟对象,它是jQuery 1.5版本引入的一种回调函数的解决方案,代表了将要完成的某种操作,并且提供了一些方法,帮助用户使用。 @H_301_0@deferred对象是对Promises接口的实现。jQuery 1.5版本以及之后所有的Ajax返回的jqXHR对象就是一个deferred对象。 @H_301_0@2.deferred对象的几大好处 2.1.为同一操作指定多个回调函数 deferred对象的好处之一,就是它允许你为一个操作添加多个回调函数,这在传统的ajax中是无法实现的。var dfd = $.Deferred();
dfd.done(f1).fail(f2).always(f3);
@H_301_0@如果在状态更改后附件一个callback则会立即执行callback,因此不必担心deferred对象何时被resolved或者rejected,因为无论何时,参数都会正确地传递给callbacks。
dfd.done(f1).fail(f2).always(f3);
//if
dfd.resolve(); //'done' 'always'
//if
dfd.reject(); //'fail' 'always'
// Resolve after a random interval
setTimeout(function () {
dfd.resolve("hurray");
},Math.floor(400 + Math.random() * 2000));
// Reject after a random interval
setTimeout(function () {
dfd.reject("sorry");
},Math.floor(400 + Math.random() * 2000));
// Show a "working..." message every half-second
setTimeout(function working() {
if (dfd.state() === "pending") {
dfd.notify("working... ");
setTimeout(working,500);
}
},1);
// Return the Promise so caller can't change the Deferred
return dfd.promise();
}
// Attach a done,and progress handler for the asyncEvent
$.when(asyncEvent()).then(
function (status) {
alert(status + ",things are going well");
},function (status) {
alert(status + ",you fail this time");
},function (status) {
alert(status);
}
);
// Set object as a promise
dfd.promise(obj);
@H_301_0@(7)$.when(deferreds) -- 提供一种方法来执行一个或多个对象的回调函数。
@H_301_0@参数:type(Deferred),一个或多个延迟对象,或者普通的JavaScript对象。
@H_301_0@参数仅传入一个单独的Deferred对象,返回它的Promise对象。
dfd.promise(obj);
// Resolve the deferred
dfd.resolve("John");
// Use the object as a Promise
obj.done(function (name) {
obj.hello(name); // will alert "Hello John"
}).hello("Karl");
$.when(func()).done(function (arg) {
alert(arg); /alert "hurry"/
});
@H_301_0@参数传入一个非Deferred和Promise对象,那么该参数会被当成一个被解决(resolved)的延迟对象,并且绑定到上面的任何doneCallbacks都会被立即执行。
alert(arg); /alert "hurry"/
});
$.when( d1,d2 ).done(function ( v1,v2 ) {
console.log( v1 ); // "Fish"
console.log( v2 ); // "Pizza"
});
@H_301_0@(8)deferred.then(doneFilter [,failFilter] [,progressFilter]) -- 当Deferred(延迟)对象解决,拒绝或仍在进行中时,调用添加处理程序。
@H_301_0@参数:
@H_301_0@doneFilter -- type(Function),当Deferred(延迟)对象得到解决时被调用的一个函数。
failFilter -- type(Function),当Deferred(延迟)对象拒绝时被调用的一个函数,可选。
progressFilter -- type(Function),当Deferred(延迟)对象生成进度通知时被调用的一个函数,可选。
其实,then方法可以理解成,把done(),fail(),progress()合在一起写。
console.log( v1 ); // "Fish"
console.log( v2 ); // "Pizza"
});
d1.resolve( "Fish" );
d2.resolve( "Pizza" );
var defer = $.Deferred(),filtered = defer.then(null,function (value) {
return value * 3;
});
@H_301_0@(9)deferred.always(alwaysCallbacks [,alwaysCallbacks]) -- 当Deferred(延迟)对象解决或拒绝时,执行alwaysCallbacks。
@H_301_0@顾名思义,只要Deferred对象的状态发生更改(解决或者拒绝)均会调用alwaysCallbacks。
@H_301_0@(10)deferred.state() -- 获取一个Deferred(延迟)对象的当前状态,不接受任何参数。
@H_301_0@$.Deferred().state();//"pending"
上面讲述过deferre(延迟)对象的三种状态,这个方法对于debug非常有用,例如,在准备reject一个deferred对象之前,判断它是否处于resolved状态。
@H_301_0@(11)deferred.notify(args) and deferred.notifyWith()
@H_301_0@(12)deferred.progress()
@H_301_0@(13)deferred.pipe()
@H_301_0@(14).promise()
@H_301_0@(15)deferred.isRejected() 和 deferred.isResolved() -- 从jQuery 1.7开始被弃用,较新版本的jQuery类库中已经被删除,可以使用state()方法代替这两个方法。
@H_301_0@(16)deferred.pipe() -- 从jQuery 1.8开始被弃用。
@H_301_0@4.什么情况下使用deferred对象和Promises?
上面讲了很多,那么我们究竟在什么情况下使用Deferred对象和Promises对象呢?
@H_301_0@(1)复杂的动画
@H_301_0@不知道动画什么时候结束,但是又必须在动画结束的时候做一些操作或者是启动其他的动画,这种情况下,如果采用其他的方式,很容易导致代码可读性差,尤其是还夹带着一些其它的操作,比如渲染、表单操作等,现在jQuery会为你的动画操作返回一个Promise,这样这些动画可以进行链式操作。
@H_301_0@(2)处理队列
@H_301_0@return value * 3;
});
defer.reject(6);
filtered.fail(function (value) {
alert("Value is 3*6 = " + value);
});
代码如下: