亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

jQuery.deferred對象使用詳解

2019-11-20 10:22:23
字體:
來源:轉載
供稿:網友

一、前言
jQuery1.5之前,如果需要多次Ajax操作,我們一般會使用下面的兩種方式:

1).串行調用Ajax

$.ajax({ success: function() {   $.ajax({ success: function() {    $.ajax({ //callbacks...         });   }); });  

這種方式代碼可讀性差,效率低,晦澀難懂,調試和排錯的復雜度大。

2).并行調用Ajax

var promises = []; $.ajax({  success: function() {     promises.push('resolved');     check();   } }); $.ajax({   success: function() {     promises.push('resolved');     check();  } }); $.ajax({   success: function() {     promises.push('resolved');     check();   } }); var check = function() { //checks for all 3 values in the promises array }

這種方式對于callbacks函數調用來說已經很不錯了,并行取得數據,可讀性良好。缺點就是代碼冗長,可擴展性差,調試和排錯的復雜度高。

jQuery1.5之后,增加了deferred對象。因此可以用下面這種方式實現和上面同樣的需求。

1)Promise

var address = $.ajax({}); var tweets = $.ajax({}); var facebook = $.ajax({}); render_side_bar = function(address, tweets, facebook){   //render sidebar }render_no_side_bar = function () { }$.when(address, tweets, facebook).then(render_side_bar, render_no_side_bar)

可以看出,代碼可讀性良好,可擴展性高,并且大大降低了調試和排錯的復雜度。

那么問題來了,promises和deferred對象究竟是個什么玩意呢?

二、詳解
2.什么是deferred對象?
deferred對象即延遲對象,它是jQuery 1.5版本引入的一種回調函數的解決方案,代表了將要完成的某種操作,并且提供了一些方法,幫助用戶使用。

deferred對象是對Promises接口的實現。jQuery 1.5版本以及之后所有的Ajax返回的jqXHR對象就是一個deferred對象。

2.deferred對象的幾大好處
2.1.為同一操作指定多個回調函數
deferred對象的好處之一,就是它允許你為一個操作添加多個回調函數,這在傳統的ajax中是無法實現的。

$.ajax("test.html")  .done(function(){ alert("first success callback!");} )  .fail(function(){ alert("there is an error!"); } )  .done(function(){ alert("second success callback!");} );

2.2.為多個操作指定同一個回調函數
deferred對象的好處之二,就是它允許你為多個操作指定同一個回調函數,這在傳統的ajax中也是無法實現的。

$.when($.ajax({}), $.ajax({}))  .done(function(){ alert("success!"); })  .fail(function(){ alert("error!"); });

2.3.非Ajax操作的回調函數
deferred對象的好處之三,就是它不再拘泥于ajax操作,任意的操作(ajax操作or本地操作/異步操作or同步操作)都可以使用deferred對象,指定回調函數。

一個很典型的耗時操作

var dfd = $.Deferred(); // create a deferred object  var wait = function(dtd){    var tasks = function(){      alert("over!");      dtd.resolve(); // change the state of the deferred object from pending to resolved    };    setTimeout(tasks,50000);    return dtd;  };
$.when(wait(dtd))  .done(function(){ alert("success!"); })  .fail(function(){ alert("error!"); });

2.4.鏈式調用
jQuery中傳統的ajax操作是這樣的:

$.ajax({  url: "",   success: function(){    alert("success!");   },   error:function(){    alert("error!");   }});

其中success指定ajax操作成功后的回調函數,error指定ajax操作失敗后的回調函數。jQuery1.5版本之前,Ajax操作返回的是一個XMLHTTPRequest對象,不支持鏈式操作。1.5版本開始,ajax操作返回的是jqXHR對象,這是一個deferred對象,而deferred對象一個顯著的好處就是可以進行鏈式操作,因為deferred對象的所有方法返回的均是deferred對象。

現在的ajax操作的寫法是:

$.ajax({})  .done(function(){ alert("success!"); })  .fail(function(){ alert("fail!"); });

兩種寫法對比可以很明顯的看出來,done()相當于傳統ajax操作的success方法,fail()相當于傳統ajax操作的fail方法。相對于傳統的寫法,代碼可讀性提高了。

3.deferred對象的方法
3.1基本用法
(1).生成deferred對象

var dfd = $.Deferred(); //create a deferred object
(2).deferred對象的狀態

deferred對象有三種狀態

pending:表示操作處于未完成的狀態,任何deferred(延遲)對象開始于pending狀態。
resolved:表示操作成功。
rejected:表示操作失敗。
state()方法返回deferred對象的當前狀態。

$.Deferred().state(); // 'pending'$.Deferred().resolve().state(); // 'resolved'$.Deferred().reject().state(); // 'rejected'

(3).改變deferred對象的狀態

調用deferred.resolve() 或者 deferred.resolveWith()轉換Deferred(遞延)到resolved(解決)的狀態,并立即執行設置中任何的doneCallbacks。

var callbackFunc = function(){console.log(arguments[0]);}var dfd = $.Deferred();dfd.done(callbackFunc);dfd.resolve("hello"); //'hello'

調用deferred.reject() 或者 deferred.rejectWith()轉換Deferred(遞延)到rejected(拒絕)的狀態,并立即執行設置中任何的failCallbacks。

var callbackFunc = function(){console.log(arguments[0]);}var dfd = $.Deferred();dfd.fail(callbackFunc);dfd.reject("fail"); //'fail'

(4).綁定回調函數

deferred對象狀態改變的時候,會觸發回調函數。任何回調使用deferred.then(), deferred.always(), deferred.done()或者 deferred.fail()添加到這個對象都是排隊等待執行。

pending-->resolved,執行設置中任何的doneCallbacks(done()指定),參數由resolved傳遞給doneCallbacks。
pending-->rejected,執行設置中任何的failCallbacks(fail()指定),參數由resolved傳遞給failCallbacks。
pending-->resolved/rejected,執行always()指定的callbacks,參數由resolved傳遞給callbacks。

var f1 = function(){console.log("done");},    f2 = function(){console.log("fail");},    f3 = function(){console.log("always");};var dfd = $.Deferred();dfd.done(f1).fail(f2).always(f3);//ifdfd.resolve(); //'done' 'always'//ifdfd.reject(); //'fail' 'always'

如果在狀態更改后附件一個callback則會立即執行callback,因此不必擔心deferred對象何時被resolved或者rejected,因為無論何時,參數都會正確地傳遞給callbacks。

var fun1 = function(){console.log(arguments[0]);},  fun1 = function(){console.log(arguments[0]);};var dfd = $.Deferred();dfd.done(fun1);dfd.resolve("hello"); //'hello'dfd.done(fun2); //'hello'

3.2.deferred對象的方法
(1)$.Deferred([beforeStart]) -- 創建一個deferred對象,參數類型為Function,是一個在構造函數之前調用的函數。

var func = function(){console.log("start");} var dfd = $.Deferred(func); //'start' create a deferred object

(2)deferred.done(doneCallbacks [,doneCallbacks]) -- 當deferred(延遲)對象解決時,調用添加處理程序。

args:接受一個或者多個參數,所有的參數都可以是一個單一的函數或者函數數組,當deferred(延遲)對象解決時,doneCallbacks被調用?;卣{是依照他們添加的順序執行的。

var func1 = function(){console.log("1");},   func2 = function(){console.log("2");},   func3 = function(){console.log("3");};var dfd = $.Deferred();dfd.done([func1,func2],func3,[func2,func1]);dfd.resolve(); // "1 2 3 2 1"

(3)deferred.fail(failCallbacks [,failCallbacks]) -- 當deferred(延遲)對象拒絕時,調用添加處理程序。

args:接受一個或者多個參數,所有的參數都可以是一個單一的函數或者函數數組,當deferred(延遲)對象拒絕時,failCallbacks被調用?;卣{是依照他們添加的順序執行的。

var func1 = function(){console.log("1");},   func2 = function(){console.log("2");},   func3 = function(){console.log("3");};var dfd = $.Deferred();dfd.fail([func1,func2],func3,[func2,func1]);dfd.reject(); // "1 2 3 2 1"

(4)deferred.resolve(args) and deferred.resolveWith(context [,args]) -- 解決Deferred(延遲)對象,并根據給定的args參數(resolveWith給定context)調用任何doneCallbacks。

參數:args -- type(object),傳遞給回調函數(doneCallbacks)的可選的參數,

        context -- type(object),Context(上下文)作為this對象傳遞給完成回調函數(doneCallbacks)。

var func = function(arg){console.log(arg);};$.Deferred().done(func).resolve("done!"); //'done!'var func = function(arg1,arg2){console.log(arg1.name + ',' + arg2);};$.Deferred().done(func).resolve({name:'Lucy'},'How are you!'); // 'Lucy,How are you!'

resolve和resolveWith的區別就等同于fire和fireWith的區別。

var func = function () {  console.log(this.name + ',' + arguments[0] + ' ' + arguments[1] + ' ' + arguments[2]);};$.Deferred().done(func).resolveWith({ name: "Lucy" }, ["How", "are", "you!"]);//'Lucy,How are you!'

(5)deferred.reject(args) and deferred.rejectWith(context [,args]) -- 拒絕Deferred(延遲)對象,并根據給定的args參數(rejectWith給定context)調用任何failCallbacks。

參數:args -- type(object),傳遞給回調函數(doneCallbacks)的可選的參數,

        context -- type(object),Context(上下文)作為this對象傳遞給完成回調函數(doneCallbacks)。

var func = function(arg){console.log(arg);};$.Deferred().fail(func).reject("error!"); //'error!'var func = function(ctx,arg){console.log(ctx.name + ',' + arg);};$.Deferred().fail(func).reject({name:'Mark'},'What happend!'); // 'Mark,What happend!'

reject和rejectWith的區別就等同于fire和fireWith的區別。

var func = function () {  console.log(this.name + ',' + arguments[0] + ' ' + arguments[1]);};$.Deferred().fail(func).rejectWith({ name: "Mark" }, ["what", "happend!"]); // 'Mark,What happend!'

(6)deferred.promise([target]) -- 返回Deferred(延遲)的Promise(承諾)對象。

 參數可選,無參數時返回一個Promise(承諾)對象,Promise(承諾)對象僅會暴露那些需要綁定額外的處理或判斷狀態的延遲方法(then, done, fail, always,pipe, progress, state,和 promise)時,并不會暴露任何用于改變狀態的延遲方法(resolve, reject, notify,resolveWith, rejectWith, 和 notifyWith)。使用Promise(承諾)會阻止其他人破壞你制造的promise。

function asyncEvent() {   var dfd = jQuery.Deferred();    // 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, fail, 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);    });

有參數時,會將事件綁定到參數上,然后返回該參數對象(返回的實際是一個擴展的Promise(承諾)對象)。

var obj = {  hello: function (name) {    alert("Hello " + name);  }},// Create a Deferreddfd = $.Deferred();// Set object as a promisedfd.promise(obj);// Resolve the deferreddfd.resolve("John");// Use the object as a Promiseobj.done(function (name) {   obj.hello(name); // will alert "Hello John"}).hello("Karl");

(7)$.when(deferreds) -- 提供一種方法來執行一個或多個對象的回調函數。

參數:type(Deferred),一個或多個延遲對象,或者普通的JavaScript對象。

參數僅傳入一個單獨的Deferred對象,返回它的Promise對象。

function func() {  var dfd = $.Deferred();  setTimeout(function () {    dfd.resolve("hurry");  }, 500);  return dfd.promise();};$.when(func()).done(function (arg) {  alert(arg); /*alert "hurry"*/});

參數傳入一個非Deferred和Promise對象,那么該參數會被當成一個被解決(resolved)的延遲對象,并且綁定到上面的任何doneCallbacks都會被立即執行。

$.when( { name: 123 } ).done(  function(arg) { alert(arg.name); } /* alerts "123" */);

無參數,返回一個resolved(解決)狀態的Promise對象。

$.when().state(); // "resolved"

參數為多個Deferred對象,該方法根據一個新的“宿主” Deferred(延遲)對象,跟蹤所有已通過Deferreds聚集狀態,返回一個Promise對象。當所有的延遲對象被解決(resolve)時,“宿主” Deferred(延遲)對象才會解決(resolved)該方法,或者當其中有一個延遲對象被拒絕(rejected)時,“宿主” Deferred(延遲)對象就會reject(拒絕)該方法。

var d1 = $.Deferred();var d2 = $.Deferred(); $.when( d1, d2 ).done(function ( v1, v2 ) {  console.log( v1 ); // "Fish"  console.log( v2 ); // "Pizza"}); d1.resolve( "Fish" );d2.resolve( "Pizza" );

(8)deferred.then(doneFilter [,failFilter] [,progressFilter]) -- 當Deferred(延遲)對象解決,拒絕或仍在進行中時,調用添加處理程序。

參數:

doneFilter --   type(Function),當Deferred(延遲)對象得到解決時被調用的一個函數。
failFilter --   type(Function),當Deferred(延遲)對象拒絕時被調用的一個函數,可選。
progressFilter --   type(Function),當Deferred(延遲)對象生成進度通知時被調用的一個函數,可選。
其實,then方法可以理解成,把done(),fail(),progress()合在一起寫。

var filterResolve = function () {   var dfd = $.Deferred(),     filtered = dfd.then(function (value) { return value * 2; });   dfd.resolve(5);   filtered.done(function (value) { console.log(value); });};filterResolve(); //'10'var defer = $.Deferred(),   filtered = defer.then(null, function (value) {     return value * 3;   });defer.reject(6);filtered.fail(function (value) {   alert("Value is 3*6 = " + value);});

(9)deferred.always(alwaysCallbacks [,alwaysCallbacks]) -- 當Deferred(延遲)對象解決或拒絕時,執行alwaysCallbacks。

 顧名思義,只要Deferred對象的狀態發生更改(解決或者拒絕)均會調用alwaysCallbacks。

(10)deferred.state() -- 獲取一個Deferred(延遲)對象的當前狀態,不接受任何參數。

$.Deferred().state();//"pending"
上面講述過deferre(延遲)對象的三種狀態,這個方法對于debug非常有用,例如,在準備reject一個deferred對象之前,判斷它是否處于resolved狀態。

(11)deferred.notify(args) and deferred.notifyWith()

(12)deferred.progress()

(13)deferred.pipe()

(14).promise()

(15)deferred.isRejected() 和 deferred.isResolved() --  從jQuery 1.7開始被棄用,較新版本的jQuery類庫中已經被刪除,可以使用state()方法代替這兩個方法。

(16)deferred.pipe() -- 從jQuery 1.8開始被棄用。

4.什么情況下使用deferred對象和Promises?
上面講了很多,那么我們究竟在什么情況下使用Deferred對象和Promises對象呢?

(1)復雜的動畫

不知道動畫什么時候結束,但是又必須在動畫結束的時候做一些操作或者是啟動其他的動畫,這種情況下,如果采用其他的方式,很容易導致代碼可讀性差,尤其是還夾帶著一些其它的操作,比如渲染、表單操作等,現在jQuery會為你的動畫操作返回一個Promise,這樣這些動畫可以進行鏈式操作。

(2)處理隊列

復制代碼 代碼如下:
window.queue = $.when() $('#list').on('click', function() { window.queue = window.queue.then(function() { //do the thing }) } )

(3)The Wait promise

function wait(ms) {   var deferred = $.Deferred();   setTimeout(function(){deferred.resolve()}, ms);  return deferred.promise(); }wait(1500).then(function () {    // After 1500ms this will be executed });

(4)典型的Ajax操作

$.when($.ajax({}), $.ajax({}))  .done(function(){ alert("success!"); })  .fail(function(){ alert("error!"); });

(5)一些耗時的大循環操作

以上就是本文的全部內容,希望對大家的學習有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91久久精品日日躁夜夜躁国产| 欧美精品精品精品精品免费| 亚洲小视频在线| 日韩av大片在线| 日韩一区二区精品视频| 久久久免费高清电视剧观看| 欧美猛少妇色xxxxx| 亚洲精品欧美日韩| 91在线中文字幕| 日韩欧美在线观看| 亚洲欧洲一区二区三区在线观看| 成人信息集中地欧美| 久久精品欧美视频| 国产一区二区色| 精品毛片三在线观看| 亚洲91精品在线观看| 欧美激情高清视频| 国产日韩欧美成人| 欧美日韩裸体免费视频| 91精品国产99久久久久久| 欧美日韩免费在线| 波霸ol色综合久久| 97人人模人人爽人人喊中文字| 亚洲韩国青草视频| 成人福利网站在线观看| 亚洲成人激情在线观看| 日本aⅴ大伊香蕉精品视频| 一本一本久久a久久精品牛牛影视| 日韩人体视频一二区| 亚洲欧美日韩中文在线制服| 亚洲999一在线观看www| 国产欧美欧洲在线观看| 91麻豆国产语对白在线观看| 久久久久久亚洲| 91免费看视频.| 欧美亚洲伦理www| 亚洲尤物视频网| 欧美一区二区大胆人体摄影专业网站| 亚洲综合国产精品| 成人xvideos免费视频| 成人黄色av网站| 第一福利永久视频精品| 国产欧美精品在线| 97在线看福利| www国产精品com| 欧美日韩国产影院| 欧美wwwxxxx| 亚洲性线免费观看视频成熟| 欧美日韩亚洲网| 国产精品视频播放| 最好看的2019年中文视频| 18性欧美xxxⅹ性满足| 国产脚交av在线一区二区| 精品丝袜一区二区三区| 免费97视频在线精品国自产拍| 色婷婷综合久久久久中文字幕1| www.xxxx欧美| 国产精品18久久久久久麻辣| 中文字幕久热精品视频在线| 蜜月aⅴ免费一区二区三区| 亚洲精品福利资源站| 亚洲美女免费精品视频在线观看| 欧美一级片免费在线| 九九视频直播综合网| 欧美三级欧美成人高清www| 国产aⅴ夜夜欢一区二区三区| 亚洲欧美另类中文字幕| 久久香蕉国产线看观看av| 亚洲视频精品在线| 久久久中精品2020中文| 国产一区二区三区在线免费观看| 国产成人精品亚洲精品| 狠狠躁夜夜躁人人爽超碰91| 亚洲国产精品电影在线观看| 国产69精品99久久久久久宅男| 日韩人在线观看| 日韩中文字幕在线精品| 性欧美视频videos6一9| 亚洲视频视频在线| 精品国产欧美成人夜夜嗨| 黄色精品在线看| 国产这里只有精品| 欧美激情va永久在线播放| 国产精品视频中文字幕91| 久久琪琪电影院| 国产91色在线免费| 亚洲综合中文字幕68页| 国产日韩av在线播放| 亚洲大胆人体在线| 日韩欧美国产一区二区| 久久久久免费精品国产| 久久免费福利视频| 狠狠躁夜夜躁人人躁婷婷91| 久久久人成影片一区二区三区观看| 国产日韩av高清| 性色av一区二区三区| 中文字幕亚洲一区| 国产精品视频在线观看| 在线播放日韩精品| 欧美日韩精品在线播放| 国产日韩欧美在线视频观看| 免费不卡在线观看av| 91亚洲精品久久久久久久久久久久| 992tv成人免费视频| 国产亚洲精品一区二555| 亚洲人成电影网站色www| 久久色在线播放| 国产精品综合不卡av| 日韩精品免费综合视频在线播放| 日韩一区视频在线| 欧美制服第一页| 欧美一区二区影院| 亚洲国产中文字幕久久网| 美女精品视频一区| 欧美色videos| 欧美日韩美女在线观看| 亚洲精品视频免费在线观看| 亚洲美女性生活视频| 国产成人精品一区二区三区| 91成人性视频| 成人亚洲欧美一区二区三区| 亚洲国产成人爱av在线播放| 亚洲色图国产精品| 亚洲国产小视频| 日韩av男人的天堂| 欧美另类极品videosbestfree| 日韩欧美福利视频| 欧美激情乱人伦| 久久久久久久国产精品| 欧美日韩成人在线观看| 国内精品久久久久影院 日本资源| 国产成人精品a视频一区www| 蜜臀久久99精品久久久无需会员| 欧美激情视频在线免费观看 欧美视频免费一| 日韩视频免费大全中文字幕| 日韩动漫免费观看电视剧高清| 国产精品久在线观看| 久久色精品视频| 日韩中文字幕在线看| 精品久久久久久久中文字幕| 欧美福利视频在线观看| 91中文字幕在线| 日韩国产在线播放| 欧美日韩国产成人高清视频| 视频在线一区二区| 国产欧美在线播放| 色多多国产成人永久免费网站| 欧美成人性生活| 97久久超碰福利国产精品…| 91高清视频免费观看| 在线日韩日本国产亚洲| 欧美在线视频免费观看| 这里精品视频免费| 成人精品网站在线观看| 国产精品久久在线观看| 久久躁狠狠躁夜夜爽| 日韩精品免费视频| 久久久成人的性感天堂| 亚洲人线精品午夜| 欧美成人免费大片| 久久国产加勒比精品无码| 国产精品美女在线观看| 欧美插天视频在线播放| 色婷婷综合久久久久中文字幕1|