亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

jQuery.Callbacks()回調函數隊列用法詳解

2019-11-20 09:42:25
字體:
來源:轉載
供稿:網友

本文實例講述了jQuery.Callbacks()回調函數隊列用法。分享給大家供大家參考,具體如下:

1、jQuery.Callbacks

The jQuery.Callbacks() function, introduced in version 1.7, returns a multi-purpose object that provides a powerful way to manage callback lists. It supports adding, removing, firing, and disabling callbacks.

The $.Callbacks() function is internally used to provide the base functionality behind the jQuery $.ajax() and $.Deferred() components. It can be used as a similar base to define functionality for new components.

接下來,我們分別看下四個標準的控制標志。

1.1 once

創建的 callbacks 對象只允許被 fireWith() 一次 [注意:方法fire() 是 fireWith() 的外觀模式]。

var callbacks = $.Callbacks("once");callbacks.add(function(){console.log("f1");});callbacks.fire(); //輸出 "f1"callbacks.fire(); //什么也不發生,在源碼中已經禁用了 list.disable()

1.2 memory

在調用 add() 方法時,如果這時 callbacks隊列 滿足 fired && firing = false(真執行完畢) && memory(需要在構造函數指定),那么add() 進去的回調函數會立即執行,而這個 add 進去的回調函數調用時的參數存儲在 memory 變量中。memory 變量用于存儲最后一次調用 callbacks.fireWith(...) 時所使用的參數 [context, arguments]。

If the Callbacks object is created with the "memory" flag as its argument, additional functions may be added and fired after the callback list is locked.

$(function($){    var callbacks = $.Callbacks("memory");    callbacks.add(function(){console.log("f1");});    callbacks.fire(); //輸出 "f1",這時函數列表已經執行完畢!    callbacks.add(function(){console.log("f2");});  //memory作用在這里,沒有fire,一樣有結果: f2    callbacks.fire(); //重新觸發一次,輸出 f1 f2。 firingStart = 0    //與once一起使用    callbacks = $.Callbacks("once memory");    callbacks.add(function(){console.log("f3");});    callbacks.fire(); //輸出 "f3",這時函數列表已經執行完畢!    callbacks.add(function(){console.log("f4");});      //沒有fire,一樣有結果: f4    callbacks.fire(); //由于為"once",這里將什么也不執行});

1.3 unique

回調函數列表中的函數是否可以重復,該特性與 add() 方法有關,可以避免在回調函數列表中加入多個相同回調函數。

var f1 = function(){console.log("f1");};var callbacks = $.Callbacks();callbacks.add(f1);callbacks.add(f1);callbacks.fire(); //輸出 f1 f1//傳遞參數 "unique"callbacks = $.Callbacks("unique");callbacks.add(f1); //有效callbacks.add(f1); //添加不進去callbacks.fire(); //輸出: f1

1.4 stopOnFalse

默認情況下,當執行 fireWith() 方法時,整個回調函數列表中的所有函數都會順序執行,但如果設置了stopOnFalse,那么當某個函數返回false時,后邊的函數將不再執行。即使設置了memory,再次添加的函數也不會執行了,即一旦某個函數返回 false 的情況下,會禁用 memory 功能。但如果沒設置”once”,再次調用fire可以重新觸發該callbacks。

var f1 = function(){console.log("f1"); return false}; //注意 return false;var f2 = function(){console.log("f2");};var callbacks = $.Callbacks();callbacks.add(f1);callbacks.add(f2);callbacks.fire(); //輸出 f1 f2callbacks = $.Callbacks("memory stopOnFalse");callbacks.add(f1);callbacks.add(f2);callbacks.fire(); //只輸出 f1callbacks.add(function(){console.log("f3");}); //不會輸出,memory已經失去作用了callbacks.fire(); //重新觸發,輸出f1

2. memory 回調隊列

var i = 0;var inc = function (s){ i++; alert(i +"$" + s);};var callbacks = $.Callbacks('memory');callbacks.add(function iteral() { callbacks.add(inc); if (i <= 1) {  callbacks.fire(i); }});callbacks.fire(i);callbacks.add(inc);/*list = [];list = [it];--->fire(0), i=01、list = [it, inc]2、push(fire(0))3、i++ [inc(0)] (i=1)shift()--->fire(0), i=11、list = [it, inc, inc];2、push(fire(1)),3、i++ [inc(0)]4、i++ [inc(0)] (i=3)shift()--->fire(1),i=31、list = [it, inc, inc, inc];2、i++ [inc(1)]3、i++ [inc(1)]4、i++ [inc(1)] (i=6)--->add(inc), i=6, memory=[this,1]1、i++ [inc(1)] (i=7)*/

3、 jQuery.CallBacks 源碼

說明:為了便于理解,修改了部分源碼,減少了一些功能~~~

jQuery.Callbacks = function (options) {  // string --> object 改進建議:將未配置的參數缺省為false,而不是undefined。便于程序閱讀和控制.  options = optionsCache[options] || createOptions(options);  var firing,    memory, //Last fire value [context, args] (for memory lists)    fired,    firingLength,    firingIndex,    firingStart,    list = [],    stack = options.once === true ? false : [], // Stack of fire calls for repeatable lists    fire = function (data) { // data --> [context, args]      memory = !!options.memory && data; // false OR [context, arguments]      fired = true;      firingIndex = firingStart || 0;      firingStart = 0;      firingLength = list.length;      firing = true;      // 這里 list 放在條件判斷中是因為執行回調函數可能會改變 list 的狀態,比如 this.disable()。      for ( ; list && firingIndex < firingLength; firingIndex++) {        if (list[firingIndex].apply(data[0], data[1]) === false && options.stopOnFalse === true) {          memory = false; // 禁止 memory 功能,這樣調用 add() 增加新回調函數不會立即自動調用          break;        }      }      firing = false;      if (list) {        if (stack) {        //進入條件: fired && firing === false && stack, 實現遞歸調用          if (stack.length) {            fire(stack.shift()); // [[context1, arguments1], [context2, arguments2]]          }        } else if (memory) {        // 進入條件: fired && firing === false && stack === undefined && 有memory字段(memory變量只能通過fire()函數修改)        // 這里的 list = [],主要是用于性能優化,以防該對象長時間不執行,占用系統內存          list = [];        } else {        // 進入條件: fired && firing === false && stack === undefined && 沒有memory字段, 說明必要繼續保留的必要          self.disable();        }      }    },    self = {      add: function() {        if (list) {                  //幾乎所有API都應該綁定這個條件,因為我們需要處理隊列          var originLength = list.length;          jQuery.each(arguments, function( _, arg) {            if (jQuery.type(arg) === "function") {                // (!(options.unique && self.has(arg))) unique字段的作用                if (!options.unique || !self.has(arg)) {                  list.push(arg);                }            }          });          if (firing === true) {          // 進入條件: 說明正在執行回調函數隊列中,而當前執行的這個回調函數激活了add()函數,及時維護循環邊界            firingLength = list.length;          } else if (memory) {          // 進入條件: memory && fired && firing === false, 說明之前的 fire() 行為已經完全結束            firingStart = originLength;            fire(memory);          }        }        return this;      },      remove: function() {        if (list) {          jQuery.each(arguments, function( _, arg) {            var lastIndex;            while ((lastIndex = jQuery.inArray(arg, list, lastIndex)) >= 0) {              list.splice(lastIndex, 1);              if (firing === true) {         // 及時更新邊界條件,實現智能處理                if (lastIndex <= firingLength) {                  firingLength--;                }                if (lastIndex <= firingIndex) {                  firingIndex--;                }              }            }          });        }        return this;      },      has: function (func) { //這個API有兩個功能,根據單一職責角度來說,應該增加一個 isNotEmpty() 接口(非空)        return func ? jQuery.inArray(func, list) > -1 : !!(list && list.length);      },      empty: function() {        list = [];        return this;      },      disable: function() { // 徹底禁用該對象, stack禁用, memory禁用        list = stack = memory = undefined;        return this;      },      disabled: function() {        return !list;      },      lock: function() {        stack = undefined;        // 如果memory沒有存儲調用狀態,直接禁用這個對象(可能是從未調用就被鎖定,或者沒有memory字段)        if (!memory) {          self.disable();        }        return this;      },      locked: function() {        return !stack;      },      fireWith: function (context, args) {        args = args || [];        var data = [context, args];        if (list && (fired === false || stack) ) {          if (firing) {     // 進入條件:  firing === true && stack  說明當前正在執行回調函數隊列            stack.push(data);      // stack其實是一個隊列結構,這里用 stack 有些混淆          } else {     // 進入條件一: firing === false && fired === false        說明從來沒有 fire()過     // 進入條件二: firing === false && fired === true && stack = [] 說明至少調用過一次,而且當前允許多次調用,可以通過lock()鎖定            fire(args);          }        }        return this;      },      fire: function() {        self.fireWith(this, arguments);        return this;      },      fired: function() {        return !!fired;      }    };  return self;};

4、胡思亂想

jQuery.Callbacks() 方法的核心是 fire() 方法,將該 fire() 方法被封裝在函數中不可直接訪問,因此像 memory、firing、fired 這些狀態對于外部上下文來說是不可更改的。

還有需要注意的是,如果回調函數中使用了 this 對象,可以直接用這個 this 來訪問self對象的公有API。當然,也可以用 fireWith() 自己指定 this 的引用對象。

jQuery.Callbacks()的核心思想是 Pub/Sub 模式,建立了程序間的松散耦合和高效通信。

更多關于jQuery相關內容感興趣的讀者可查看本站專題:《jQuery常用插件及用法總結》、《jquery中Ajax用法總結》、《jQuery表格(table)操作技巧匯總》、《jQuery拖拽特效與技巧總結》、《jQuery擴展技巧總結》、《jQuery常見經典特效匯總》、《jQuery動畫與特效用法總結》及《jquery選擇器用法總結

希望本文所述對大家jQuery程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
蜜臀久久99精品久久久久久宅男| 91香蕉嫩草神马影院在线观看| 日韩极品精品视频免费观看| 欧美日韩亚洲高清| 国产成人免费av| 成人黄色av免费在线观看| 国产精品视频免费在线| 成人黄色av网| 国产盗摄xxxx视频xxx69| 91av在线影院| 91久久久久久久久久久| 色婷婷av一区二区三区在线观看| 亚洲人成伊人成综合网久久久| 美女撒尿一区二区三区| 欧美成人精品在线播放| 成人信息集中地欧美| 亚洲日本欧美日韩高观看| 91av视频在线观看| 亚洲男人的天堂在线播放| 国内精品视频久久| 日韩福利伦理影院免费| 久久精品视频va| 97在线视频一区| 亚洲精品久久久久久久久久久| 青青久久av北条麻妃黑人| 亚洲精品乱码久久久久久按摩观| 亚洲综合社区网| 91探花福利精品国产自产在线| 最近2019年中文视频免费在线观看| 亚洲精品视频二区| 国产精品欧美亚洲777777| 亚洲欧洲国产伦综合| 国产一区二区三区久久精品| 国产女精品视频网站免费| 欧美成人午夜激情| 久久成人精品一区二区三区| 日本精品久久中文字幕佐佐木| 欧美国产精品日韩| 国产精品av在线| 国产欧美韩国高清| 国产精品久久久久久久7电影| 国内精品视频一区| 7777精品视频| 亚洲国模精品一区| 久久久久久久久中文字幕| 久久九九亚洲综合| 97在线观看免费高清| 国产精品国产三级国产专播精品人| 成人性生交大片免费观看嘿嘿视频| 亚洲欧美在线一区二区| 欧美野外wwwxxx| 91精品国产亚洲| 成人444kkkk在线观看| 亚洲片国产一区一级在线观看| 国产精品久久久久久av下载红粉| 中文字幕自拍vr一区二区三区| 国产精品日韩欧美大师| 日韩中文字幕国产| 欧美在线一级va免费观看| 亚洲福利视频网| 国产精品视频内| 久久久久久久久久久久av| 国产成人精品久久亚洲高清不卡| 在线视频欧美性高潮| 国产精品视频网站| 欧美日韩中文字幕综合视频| 亚洲午夜久久久久久久| 国产精品香蕉国产| 亚洲福利视频二区| 国产97在线视频| 黑人巨大精品欧美一区二区| 大桥未久av一区二区三区| 国产精品视频在线播放| 97在线视频一区| 欧美黄色性视频| 亚洲国产精品大全| 久久亚洲精品国产亚洲老地址| 另类专区欧美制服同性| 色青青草原桃花久久综合| 成人妇女免费播放久久久| 91av视频导航| 国产精品免费久久久久影院| 久久色精品视频| 成人免费高清完整版在线观看| 欧美丰满少妇xxxxx做受| 国产精品扒开腿做爽爽爽视频| 成人亚洲综合色就1024| 欧美视频中文字幕在线| 美女av一区二区三区| 亚洲欧美激情在线视频| 最新国产成人av网站网址麻豆| 久久久久中文字幕| 91精品久久久久久久久久久| 成人精品视频99在线观看免费| 精品成人国产在线观看男人呻吟| 日韩美女毛茸茸| 成人妇女免费播放久久久| 欧美激情aaaa| 在线视频精品一| 高清日韩电视剧大全免费播放在线观看| 日本亚洲欧美成人| 96sao精品视频在线观看| 久久91亚洲精品中文字幕| 亚洲国产精品va在线观看黑人| 国内精品中文字幕| 亚洲精品www| 一色桃子一区二区| 久久久久久高潮国产精品视| 中文字幕亚洲天堂| 91九色国产视频| 国产亚洲欧美另类中文| 亚洲视频自拍偷拍| 日韩美女在线播放| 久久精品电影一区二区| 亚洲最大福利网站| 国产精品99久久99久久久二8| 97福利一区二区| 国产拍精品一二三| 国产一区香蕉久久| 国产日韩精品电影| 国产精品美女在线观看| 日本欧美在线视频| 久久这里有精品视频| 91免费视频网站| 日韩视频免费观看| 国产精品久久久久久久7电影| 午夜精品久久久久久久久久久久久| 欧美激情亚洲综合一区| 久久av在线播放| 欧美福利小视频| 欧美成人免费全部观看天天性色| 日韩欧美成人区| 欧美wwwxxxx| 国产精品综合不卡av| 日韩不卡中文字幕| 97人人做人人爱| 亚洲欧美制服中文字幕| 欧美中文字幕在线观看| 日韩高清电影免费观看完整版| 亚洲国产精品美女| 色综合五月天导航| 国产精品国产三级国产aⅴ浪潮| 久久av.com| 久久久久久久久久久av| 日韩欧美成人免费视频| 一区二区三区 在线观看视| 成人黄色免费在线观看| 国产69久久精品成人看| 亚洲www永久成人夜色| 欧美日韩福利电影| 成人乱色短篇合集| 黄色精品在线看| 日韩美女视频免费看| 成人激情春色网| 欧美日韩国产丝袜另类| 国产亚洲日本欧美韩国| 91高清免费视频| 日日摸夜夜添一区| 亚洲va码欧洲m码| 成人h视频在线| 最新日韩中文字幕| 欧美性猛交xxxx偷拍洗澡| 日韩美女毛茸茸| 国产午夜精品全部视频在线播放|