看板 Ajax 關於我們 聯絡資訊
本篇可以參考: 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)
nightspirit:ajax如果要做queue的話,可以直接用deferred 04/18 01:08
davidsky:deferred好用+1 04/21 04:01
epenpal:大推、對我非常有用 05/04 16:47
jimpop:淚推這篇~~太讚了!! 06/22 16:31