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