Re: [閒聊] JQuery的callback與queue

看板Ajax作者 (沉默是金。)時間15年前 (2010/08/27 23:31), 編輯推噓4(405)
留言9則, 4人參與, 最新討論串3/4 (看更多)
有關 queue 的觀念這問題就交給我吧, 我跟 jquery queue 打過很多次交道了。 jQuery 的 queue 其實蠻複雜的, 因為除 context 外還加入 namespace 的觀念,所以用起來會有點困惑。 另外 jQuery queue 有個特例, 所以用起來會怎麼怪怪的也很正常,因為你被特例騙了。 先講什麼是namespace , 簡單來講他可以允許多條 queue 同時存在。 你可以今天 $.queue("hello",function(){alert("hi");} ); 這樣是一條叫hello的queue 又可以有另一條 $.queue("hello2",function(){alert("hi");} ); 兩條是平行支線這樣。 然後 default 的 queue 叫 fx , 最重要的重點是所有 jQuery effect 都掛這個 queue, 所以 fadeIn / fadeOut 也都是掛在這個queue上。 所以 s25g5d4 的這個 sample 中,所有包著fadeIn / fadeOut的, 都以看成是 xxx.queue("fx",dosomething) , 所以其實是個很複雜的Queue行為,不太適合作為說明 要測的話應該拿show/hide這種沒什麼影響的行為測, 或者用別的名字的 queue 測,這樣 queue 跟dequeue行為就會很清楚。 然後假設是同一條支線底下,我queue跟dequeue就是表示, 推進去跟開始執行的時機。 其實他不是所謂的「停下來等你」, 他就是把 function 推到 queue array , 你呼叫 deqeueue 他就跑一個,執行下一個 dequeue 再跑一個, 直到沒 dequeue 或 dequeue 沒東西為止。 queue 中間你要 setTimeout /ajax 還是要幹麼這都隨你, 重點就是什麼時候你呼叫dequeue。 所以假設你都沒有做任何非同步的行為(setTimeout/setInterval/ajax), 那其實他是會在之後程式執行之前先執行的。 ----------------------------------------------------- 上面都是奇怪又複雜的理論說明,底下走實務例子路線。XD 1. 一般正常狀況來講,你 queue 進去的東西, 不執行 dequeue他是不會run的。 所以這個 沒 dequeue 的 sample 中 queue 不會run . http://jsfiddle.net/hJ8L8/ 2. 不過當我們 dequeue之後,就又會run了。 http://jsfiddle.net/hJ8L8/2/ 3. 再來我們試著增加一些 queue 來做測試 這個 sample 中有兩個 queued function , 不過因為dequeue只有一次, 所以實際上只有一個函式被執行 . http://jsfiddle.net/hJ8L8/3/ 4. 接下來我們在 queue 1 中加入 dequeue 告訴他我跑完了。 http://jsfiddle.net/hJ8L8/4/ 然後我們剛剛不是有提到,queue到底是不是同步的? 所以我們再加個訊息來討論。 http://jsfiddle.net/hJ8L8/5/ 你會發現,其實他是跑進 dequeue 執行完後才又出來的。 5. 那來玩玩不一樣的 dequeue 吧! 在這個 example 中,我們在 queue1 執行dequeue之前跑 timeout, 結果 queue2 在timeout之後才被dequeue。 http://jsfiddle.net/hJ8L8/6/ 所以結論是什麼時候執行下一個,純粹是靠dequeue來決定。 ----------------------------------------------------- 其實在用queue 的時候比較建議一次塞好要做的事情再開始執行, 因為他有個很麻煩的特性,一旦dequeue找不到東西時就會中斷, 即使你之後再塞東西給他,他也不會執行, 然後你又不可能定期去dequeue 。 (這樣就失去 queue的意義了,還不如用interval。) 這個問題可以用這個 sample 表示, 你會發現 http://jsfiddle.net/hJ8L8/7/ queue2 等在佇列中沒執行了。 但是在 queue2 進入之後的時間點再 dequeue 就會出現。 http://jsfiddle.net/hJ8L8/8/ 其實這點我一直想不通為什麼他是這樣設計的(我從1.2時代就困惑到現在), 我在猜他大概想讓使用者自己決定開關的時機, 不過這真的因此讓他變得不太好用。 (btw 官方的 queue 文件我個人覺得也是一點都沒抓到重點, fadeIn等fx系列都被包裝過了,根本看不出來他好用的地方啊... 這篇文章基本上是我讀code的心得.) 而且他還有一個特例,就是 fx 系列。 jQuery.fn.extend({ queue: function( type, data ) { if ( typeof type !== "string" ) { data = type; type = "fx"; } if ( data === undefined ) { return jQuery.queue( this[0], type ); } return this.each(function( i, elem ) { var queue = jQuery.queue( this, type, data ); if ( type === "fx" && queue[0] !== "inprogress" ) { jQuery.dequeue( this, type ); } }); }, 看黃字就好。 只要是 fx 系列,queue完後會自動dequeue。 (簡單來說,就是塞進去就自動執行。) 有這個 feature 其實好用多了, 所以我有時候也會拿一些冷門成員 body或window 的 fx queue 來用, 對一些需要連貫性執行的效果的確是好用很多。(個人習慣啦...XD) 基本上我在使用 queue 的過程中,我覺得 queue 是 jQuery 設計中, 我對他的流程跟結構設計的比較有意見的一部份。 這東西其實是強大的工具,特別是針對一些需要循序的工作, 但是如果沒有去看code,光看官方文件跟範例,大概看不出啥東東... (而且他自己都設計出 fx 這個特例了....) 是說,知道原理的話自己實做一個也不難啦, 官方板也才幾十行 code 不到而已。 -- 我:一半的日子讓你說,我聽你說你的所有______________________________________ ______________________________________一半的日子我想說,對你說過去的所有:我 _______________________________________________________ 在討論中妥善扮演兼具聆聽與分享的角色,是我們一生的課題。 _______________________________________________________ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.136.202.202 ※ 編輯: TonyQ 來自: 114.136.202.202 (08/27 23:32)

08/27 23:40, , 1F
專業人士到了 我去旁邊蹲
08/27 23:40, 1F
※ 編輯: TonyQ 來自: 114.136.202.202 (08/27 23:48)

08/27 23:48, , 2F
fadseOut還是沒改 @@" 話說documention琢磨了半天也還是
08/27 23:48, 2F

08/27 23:49, , 3F
不懂queue到底是殺毀
08/27 23:49, 3F

08/27 23:57, , 4F
你把我文章中那些連結一個一個點完看懂就知道queue是啥了XD
08/27 23:57, 4F

08/27 23:58, , 5F
queue 是一種控制程式流程的工具,所以重點在流程。
08/27 23:58, 5F

08/28 00:00, , 6F
啊就是排隊喔
08/28 00:00, 6F

08/28 00:02, , 7F
有看有"花" XD
08/28 00:02, 7F

08/28 00:04, , 8F
我都把queue搭配resize event用
08/28 00:04, 8F

08/28 00:08, , 9F
queue 就是個其實概念上很簡單 但很難表達的東西 XD
08/28 00:08, 9F
※ 編輯: TonyQ 來自: 220.133.44.37 (08/30 09:08)
文章代碼(AID): #1CTzfhxg (Ajax)
文章代碼(AID): #1CTzfhxg (Ajax)