作者TonyQ (自立而後立人。)
看板Ajax
標題[心得] jQuery queue 介紹
時間Mon Apr 16 00:44:58 2012
本篇可以參考:
http://ithelp.ithome.com.tw/question/10090792
-----------------------------------
-----------------------------------
所謂的 queue ,主要是把多個「非同步」的 task 「依序」做完。
(不是說同步不行,只是同步的話,
不需要靠 queue 就會依序做完,不需要特別做 queue 。)
在 jQuery 狀況下,queue 主要是拿來作 animation 效果內部實作,
反而不多人會在正式開發用它,一方面是他難懂,
另一方面是使用者還不知道什麼時候該用 queue。
舉個例子,以 fadeIn 來講,
他是將物件顯示為顯示,並設 opacity 從 0 到 100。
如果我要自己刻一個簡易實作,直覺你可能想到要這樣作。
http://jsfiddle.net/eqAdS/
[code]
<div id="target" style="width:150px;height:150px;background:red;">
Test
</div>
<script>
var item = $("#target");
item.show();
item.css("opacity",0);
for(var i = 0 ; i < 100 ;++ i){
item.css("opacity", i / 100 );
}
item.html("fadeIn invoked");
</script>
[/code]
但是你會發現看不見效果。
因為 animation 需要有間隔時間,看起來才像 animation,
不然直接從 0 跑個迴圈到100 ,時間太短會看不到畫面呈現。
那我們下一版改為這樣的實作
http://jsfiddle.net/eqAdS/1/
[code]
<div id="target" style="width:150px;height:150px;background:red;">
Test
</div>
<script>
var item = $("#target") , time = 500;
item.show();
item.css("opacity",0);
for(var i = 0 ; i <= 100 ; i +=10){
//use ind to protect variable "i",or it will always be 100
(function(ind){
//put all the process into queue
$("#target").queue("fadeIn",function(){
item.css("opacity", ind/100 );
setTimeout(function(){
//run next item
$("#target").dequeue("fadeIn");
},time); //every 500 ms
});
})(i);
}
$("#target").dequeue("fadeIn"); //start to run items!
item.html("fadeIn invoked");
</script>
[/code]
你會發現這次看起來像樣多了,他的原理是假設你有十件事情要做,
你可以先用 $(selector).queue(name,function) 推入指定的 queue ,
但是因為我們知道處理流程通常都是非同步的 (timeout / ajax ...etc ),
那系統怎麼會知道什麼時後要執行下一個呢? 答案是:它就是不知道。
所以你必須要自己告訴他,當你呼叫 $(selector).dequeue(name) 表示說,
我要開始了或我這一輪作完了,作下一輪吧!
比方說偶爾會有個需求是,我希望先做完 ajax1 ,
確定他做完了再作 ajax2 ,那就會像是以下的 code
[code]
//建立第一個排程,此時還沒執行
$("#target").queue("myqueue",function(){
//do something , like ajax
$.post("myurl.php",function(){
//run next queue item after ajax success
$("#target").dequeue("myqueue");
});
});
//建立第二個排程,此時還沒執行
$("#target").queue("myqueue",function(){
//do something , like ajax
$.post("myurl2.php",function(){
//run next queue item after ajax success
$("#target").dequeue("myqueue");
});
});
$("#target").dequeue("myqueue");//開始執行
//此時它會開始先跑 myurl.php 的 ajax ,確定 success 有收到回應後,
//再跑 myurl2.php 的ajax。
[/code]
當然他還有一些延伸用法,但這裡基於教學立場,
我們就只提到最基本該有的東西:
另外,如果因為某些因素你想清空正在執行的 queue ,
像是jQuery animation 的 stop() ,
你可以 call $(selector).clearQueue("myqueue");
附帶一提,jQuery 1.4 以後提供更方便的操作方式,
原本寫成
[code]
$("#target").queue("myqueue",function(){
//do something , like ajax
$.post("myurl.php",function(){
//run next queue item after ajax success
$("#target").dequeue("myqueue");
});
});
[/code]
可以改寫成
[code]
$("#target").queue("myqueue",function(next){ //內建傳入 next 方便作dequeue
//do something , like ajax
$.post("myurl.php",function(){
//run next queue item after ajax success
next(); //用傳進來的 next function 取代 dequeue()
});
});
[/code]
所以我們最一開始的 myFadeIn 開發範例就可以變成這樣,
寫起來可以省下不少力氣。
http://jsfiddle.net/eqAdS/2/
[code]
<div id="target" style="width:150px;height:150px;background:red;">
Test
</div>
<script>
var item = $("#target") , time = 500;
item.show();
item.css("opacity",0);
for(var i = 0 ; i <= 100 ; i +=10){
//use ind to protect variable "i",or it will always be 100
(function(ind){
//put all the process into queue
$("#target").queue("fadeIn",function(next){
item.css("opacity", ind/100 );
setTimeout(next,time); //every 500 ms
});
})(i);
}
$("#target").dequeue("fadeIn"); //start to run items!
item.html("fadeIn invoked");
</script>
[/code]
最後討論 Queue 的主要適用情境:
1.大量同時運算導致網頁卡住時,用來作為運算的分流用。
2.操作有相依性,需要等待時
(需確定 A 操作完的結果、狀態才能操作B ...etc )
3.animation
--
Life's a struggle but beautiful.
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.25.56.138
※ 編輯: TonyQ 來自: 114.25.56.138 (04/16 00:58)
1F:推 nightspirit:ajax如果要做queue的話,可以直接用deferred 04/18 01:08
2F:推 davidsky:deferred好用+1 04/21 04:01
3F:推 epenpal:大推、對我非常有用 05/04 16:47
4F:推 jimpop:淚推這篇~~太讚了!! 06/22 16:31