作者TonyQ (沉默是金。)
看板Ajax
标题Re: [闲聊] JQuery的callback与queue
时间Fri Aug 27 23:31:52 2010
有关 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)
1F:推 s25g5d4:专业人士到了 我去旁边蹲 08/27 23:40
※ 编辑: TonyQ 来自: 114.136.202.202 (08/27 23:48)
2F:→ s25g5d4:fadseOut还是没改 @@" 话说documention琢磨了半天也还是 08/27 23:48
3F:→ s25g5d4:不懂queue到底是杀毁 08/27 23:49
4F:→ TonyQ:你把我文章中那些连结一个一个点完看懂就知道queue是啥了XD 08/27 23:57
5F:→ TonyQ:queue 是一种控制程式流程的工具,所以重点在流程。 08/27 23:58
6F:推 s25g5d4:啊就是排队喔 08/28 00:00
7F:推 JYHuang:有看有"花" XD 08/28 00:02
8F:推 megaman1206:我都把queue搭配resize event用 08/28 00:04
9F:→ TonyQ:queue 就是个其实概念上很简单 但很难表达的东西 XD 08/28 00:08
※ 编辑: TonyQ 来自: 220.133.44.37 (08/30 09:08)