摘要:參考以下對比不添加參數(shù)添加參數(shù)相同的函數(shù)不會被重復(fù)添加到內(nèi)部隊列中內(nèi)部隊列里的函數(shù)是依次執(zhí)行的,當(dāng)某個函數(shù)的返回值是時,停止繼續(xù)執(zhí)行剩下的函數(shù)。
前言
$.Callbacks用來管理函數(shù)隊列。采用了觀察者模式,通過add添加操作到隊列當(dāng)中,通過fire去執(zhí)行這些操作。實際上$.Callbacks是1.7版本從$.Deferred對象當(dāng)中分離出來的,主要是實現(xiàn)$.Deferred功能。
API $.Callbacks我們通過調(diào)用$.Callbacks獲取到一個callback實例,如下
var cb = $.Callbacks();
看到Callbacks首字母大寫,有些人可能會覺得一般只有對象才會這樣,因此需要new一個實例,如下
var cb = new $.Callbacks();
實際上這兩種方式都可以,因為Callbacks函數(shù)返回值是一個對象,為什么會這樣?看下面一組對比
function Cons() { this.name = "this.name"; return { name: "obj.name" }; } console.log(Cons().name);//obj.name console.log(new Cons().name);//obj.name function Cons() { this.name = "this.name"; return "str.name"; } console.log(Cons());//str.name console.log(new Cons().name);//this.name
當(dāng)函數(shù)的返回值是一個對象時(null除外),new和直接調(diào)用兩者的返回值是一樣的。但是需要注意了,兩者的this指向是不一樣的。為了盡可能的節(jié)省代碼和避免混亂我們還是統(tǒng)一采用var cb = $.Callbacks();的方式去調(diào)用。
像這種先調(diào)用獲取到實例,然后通過實例進(jìn)行一系列的操作,很明顯利用了閉包特性。
add向內(nèi)部隊列添加函數(shù),總有三種參數(shù)形式
單個函數(shù)參數(shù)var cb = $.Callbacks(); cb.add(function () { console.log("add one"); });多個函數(shù)參數(shù)
var cb = $.Callbacks(); cb.add(function () { console.log("add one"); }, function () { console.log("add two"); });數(shù)組參數(shù)
var cb = $.Callbacks(); cb.add([ function () { console.log("add one"); }, function () { console.log("add two"); } ]);fire
依次執(zhí)行隊列里的函數(shù)
var cb = $.Callbacks(); cb.add([ function () { console.log("add one"); }, function () { console.log("add two"); } ]); cb.fire(); //add one //add two
fire的參數(shù)會傳遞給我們添加的函數(shù),例如
var cb = $.Callbacks(); cb.add(function (name, age) { console.log(name, age); }); cb.fire("Jacky", 26);//Jacky 26fireWith
fire調(diào)用的時候,我們添加函數(shù)當(dāng)中的this指向我們的Callbacks實例,例如
var cb = $.Callbacks(); cb.add(function () { console.log(this === cb); }); cb.fire();//true
fireWith就是改變我們添加函數(shù)的context,即this指向,例如
var cb = $.Callbacks(); var obj = { name: "objName" }; cb.add(function (age) { console.log(this.name, age); }); cb.fireWith(obj, [26]);//objName 26
emptyfireWith第一個參數(shù)是我們的context,第二個參數(shù)是我們需要傳遞的內(nèi)容數(shù)組,注意了是數(shù)組!
清空函數(shù)隊列
var cb = $.Callbacks(); cb.add(function () { console.log("add one"); }); cb.empty(); cb.fire();has
判斷函數(shù)隊列中是否存在某個函數(shù)
var cb = $.Callbacks(); function demo() { console.log("demo"); } cb.add(demo); console.log(cb.has(demo));//true
函數(shù)傳遞的都是引用,千萬別出現(xiàn)以下的低級錯誤
var cb = $.Callbacks(); cb.add(function () { console.log("demo"); }); cb.has(function () { console.log("demo"); });remove
從內(nèi)部隊列中移除某些函數(shù)
var cb = $.Callbacks(); function demo1() { console.log("demo1"); } function demo2() { console.log("demo2"); } cb.add(demo1, demo2); cb.remove(demo1, demo2); cb.fire();disable
禁用回調(diào)列表。這種情況會清空函數(shù)隊列,禁用核心功能。意味著這個回調(diào)管理報廢了。
var cb = $.Callbacks(); cb.add(function () { console.log("add"); }); cb.disable(); cb.fire();disabled
回調(diào)管理是否被禁用
var cb = $.Callbacks(); cb.add(function () { console.log("add"); }); cb.disable(); console.log(cb.disabled());//truelock
鎖定回調(diào)管理,同disable,唯一的差別會在下面表述
locked回調(diào)管理是否被鎖
fired回調(diào)隊列是否執(zhí)行過
var cb = $.Callbacks(); cb.add(function () { console.log("add"); }); cb.fire();//add console.log(cb.fired());//true$.Callbacks()
$.Callbacks通過字符串參數(shù)的形式支持4種及以上的特定功能。很明顯的一個工廠模式。
once函數(shù)隊列只執(zhí)行一次。參考以下對比
//不添加參數(shù) var cb = $.Callbacks(); cb.add(function () { console.log("add"); }); cb.fire();//add cb.fire();//add //添加參數(shù) var cb = $.Callbacks("once"); cb.add(function () { console.log("add"); }); cb.fire();//add cb.fire();
函數(shù)隊列執(zhí)行過以后,就不會在執(zhí)行了,無論調(diào)用fire多少次。
unique往內(nèi)部隊列添加的函數(shù)保持唯一,不能重復(fù)添加。參考以下對比
//不添加參數(shù) var cb = $.Callbacks(); function demo() { console.log("demo"); } cb.add(demo, demo); cb.fire(); //demo //demo //添加參數(shù) var cb = $.Callbacks("unique"); function demo() { console.log("demo"); } cb.add(demo, demo); cb.fire();//demo
相同的函數(shù)不會被重復(fù)添加到內(nèi)部隊列中
stopOnFalse內(nèi)部隊列里的函數(shù)是依次執(zhí)行的,當(dāng)某個函數(shù)的返回值是false時,停止繼續(xù)執(zhí)行剩下的函數(shù)。參考以下對比
//不添加參數(shù) var cb = $.Callbacks(); cb.add([ function () { console.log("add one"); }, function () { console.log("add two"); } ]); cb.fire(); //add one //add two //添加參數(shù) var cb = $.Callbacks("stopOnFalse"); cb.add([ function () { console.log("add one"); return false; }, function () { console.log("add two"); } ]); cb.fire();//add one
memory注意了返回值一定要是false,像undefined、null這種作為返回值是沒有效果的
當(dāng)函數(shù)隊列fire或fireWith一次過后,內(nèi)部會記錄當(dāng)前fire或fireWith的參數(shù)。當(dāng)下次調(diào)用add的時候,會把記錄的參數(shù)傳遞給新添加的函數(shù)并立即執(zhí)行這個新添加的函數(shù)??磦€例子
var cb = $.Callbacks("memory"); cb.add(function (name) { console.log("one", name); }); cb.fire("Jacky");//first Jacky cb.add(function (name) { console.log("two", name); });//two Jacky
例如公司領(lǐng)導(dǎo)在9點的時候發(fā)了封郵件,要求大家提交自己的年終終結(jié),這就相當(dāng)于fire操作了,在公司里的員工收到郵件后,立馬提交了。小李由于請假,下午才過來,看到郵件后也提交了自己的年終總結(jié)。不需要領(lǐng)導(dǎo)再次發(fā)送郵件提醒。
小結(jié)fire或fireWith一定要在disabled或lock前先執(zhí)行一遍,memory才會起作用
這四種基本類型可以相互組合起來使用,例如$.Deferred就使用了once和memory的組合。
jQuery.Callbacks("once memory")disable和lock的區(qū)別
兩者唯一的區(qū)別就是添加了memory參數(shù),看一下對比
var cb = $.Callbacks("memory"); cb.add(function () { console.log("one"); }); cb.fire(); cb.disable(); //cb.lock(); cb.add(function () { console.log("two"); });
毫無疑問,disable就是禁用所有功能,無論添加什么參數(shù)。而在memory的情況下,fire過后在lock,繼續(xù)add新的函數(shù)依舊會立即執(zhí)行。
總結(jié)$.Callbacks在一百多行的代碼里就用到了兩種設(shè)計模式,確實經(jīng)典。當(dāng)然了這都是純屬個人見解。由于平時用的很少,很遺憾沒有舉出代表性的例子供大家參考,畢竟我輩的目標(biāo)是學(xué)以致用。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/91607.html
摘要:的支持的方法有幾個主要的,和,比如官方有一個例子這兩個作為函數(shù)調(diào)用的生成從基本可以看出,函數(shù)生成了一個對象,這個對象的方法是添加回調(diào)函數(shù),而方法則是執(zhí)行回調(diào)函數(shù)。 歡迎來我的專欄查看系列文章。 講真,Sizzle 的源碼真的太壓抑了,以至于寫 Sizzle 文章的這段時間里都非常的痛苦,剛開始覺得它還挺有意思的,越到后面越覺得代碼很難讀懂,煩。 寒假也過完了,在家里待了兩周的時間,感覺...
摘要:作為此時不存在,直接從數(shù)據(jù)緩存中獲取并返回。作用是觸發(fā)中的回調(diào)函數(shù),的表示只讓觸發(fā)一次后,就需要清理,表示是將清空成空數(shù)組還是空字符。 showImg(https://segmentfault.com/img/remote/1460000019558449); 前言:queue()方法和dequeue()方法是為 jQuery 的動畫服務(wù)的,目的是為了允許一系列動畫函數(shù)被異步調(diào)用,但不...
摘要:我們稱為回調(diào)對象,它內(nèi)部會維護(hù)一個數(shù)組,我們可以向其中添加若干個回調(diào)函數(shù),然后在某一條件下觸發(fā)執(zhí)行。第一次之后,再次新的回調(diào)函數(shù)時,自動執(zhí)行回調(diào)。當(dāng)前面的回調(diào)函數(shù)返回時,終止后面的回調(diào)繼續(xù)執(zhí)行。 最近懶癌發(fā)作,說好的系列文章,寫了一半,一直懶得寫,今天補上一篇。 Deferred 我們在使用promise對象時,總會提到一個與它關(guān)系密切的對象——Deferred。其實Deferred沒...
摘要:回調(diào)隊列對象,用于構(gòu)建易于操作的回調(diào)函數(shù)集合,在操作完成后進(jìn)行執(zhí)行。對象對象,用于管理回調(diào)函數(shù)的多用途列表。如果傳入一個延遲對象,則返回該對象的對象,可以繼續(xù)綁定其余回調(diào),在執(zhí)行結(jié)束狀態(tài)之后也同時調(diào)用其回調(diào)函數(shù)。 在工作中我們可能會把jQuery選擇做自己項目的基礎(chǔ)庫,因為其提供了簡便的DOM選擇器以及封裝了很多實用的方法,比如$.ajax(),它使得我們不用操作xhr和xdr對象,直...
閱讀 2310·2023-04-25 14:22
閱讀 3748·2021-11-15 18:12
閱讀 1303·2019-08-30 15:44
閱讀 3224·2019-08-29 15:37
閱讀 653·2019-08-29 13:49
閱讀 3466·2019-08-26 12:11
閱讀 887·2019-08-23 18:28
閱讀 1592·2019-08-23 14:55