国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問(wèn)答文章1 問(wèn)答文章501 問(wèn)答文章1001 問(wèn)答文章1501 問(wèn)答文章2001 問(wèn)答文章2501 問(wèn)答文章3001 問(wèn)答文章3501 問(wèn)答文章4001 問(wèn)答文章4501 問(wèn)答文章5001 問(wèn)答文章5501 問(wèn)答文章6001 問(wèn)答文章6501 問(wèn)答文章7001 問(wèn)答文章7501 問(wèn)答文章8001 問(wèn)答文章8501 問(wèn)答文章9001 問(wèn)答文章9501
當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

jQuery源碼之Callbacks的學(xué)習(xí)

來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 19:34:01
文檔

jQuery源碼之Callbacks的學(xué)習(xí)

jQuery源碼之Callbacks的學(xué)習(xí):這篇文章主要介紹了關(guān)于jQuery源碼之Callbacks的學(xué)習(xí),有著一定的參考價(jià)值,現(xiàn)在分享給大家,有需要的朋友可以參考一下jQuery源碼學(xué)習(xí)之CallbacksjQuery的ajax、deferred通過(guò)回調(diào)實(shí)現(xiàn)異步,其實(shí)現(xiàn)核心是Callbacks。使用方法使用首先要先新建一個(gè)實(shí)例對(duì)
推薦度:
導(dǎo)讀jQuery源碼之Callbacks的學(xué)習(xí):這篇文章主要介紹了關(guān)于jQuery源碼之Callbacks的學(xué)習(xí),有著一定的參考價(jià)值,現(xiàn)在分享給大家,有需要的朋友可以參考一下jQuery源碼學(xué)習(xí)之CallbacksjQuery的ajax、deferred通過(guò)回調(diào)實(shí)現(xiàn)異步,其實(shí)現(xiàn)核心是Callbacks。使用方法使用首先要先新建一個(gè)實(shí)例對(duì)

這篇文章主要介紹了關(guān)于jQuery源碼之Callbacks的學(xué)習(xí),有著一定的參考價(jià)值,現(xiàn)在分享給大家,有需要的朋友可以參考一下

jQuery源碼學(xué)習(xí)之Callbacks

jQuery的ajaxdeferred通過(guò)回調(diào)實(shí)現(xiàn)異步,其實(shí)現(xiàn)核心是Callbacks

使用方法

使用首先要先新建一個(gè)實(shí)例對(duì)象。創(chuàng)建時(shí)可以傳入?yún)?shù)flags,表示對(duì)回調(diào)對(duì)象的限制,可選值如下表示。

  • stopOnFalse:回調(diào)函數(shù)隊(duì)列中的函數(shù)返回false時(shí)停止觸發(fā)

  • once:回調(diào)函數(shù)隊(duì)列只能被觸發(fā)一次

  • memory:記錄上一次觸發(fā)隊(duì)列傳入的值,新添加到隊(duì)列中的函數(shù)使用記錄值作為參數(shù),并立即執(zhí)行。

  • unique:函數(shù)隊(duì)列中函數(shù)都是唯一的

  • var cb = $.Callbacks('memory');
    cb.add(function(val){
     console.log('1: ' + val)
    })
    cb.fire('callback')
    cb.add(function(val){
     console.log('2: ' + val)
    })
    // console
    輸出 1: callback 2: callback

    Callbacks 提供了一系列實(shí)例方法來(lái)操作隊(duì)列和查看回調(diào)對(duì)象的狀態(tài)。

  • add: 添加函數(shù)到回調(diào)隊(duì)列中,可以是函數(shù)或者函數(shù)數(shù)組

  • remove: 從回調(diào)隊(duì)列中刪除指定函數(shù)

  • has: 判斷回調(diào)隊(duì)列里是否存在某個(gè)函數(shù)

  • empty: 清空回調(diào)隊(duì)列

  • disable: 禁止添加函數(shù)和觸發(fā)隊(duì)列,清空回調(diào)隊(duì)列和上一個(gè)傳入的值

  • disabled: 判斷回調(diào)對(duì)象是否被禁用

  • lock: 禁用fire,若memory非空則同時(shí)add無(wú)效

  • locked: 判斷是否調(diào)用了lock

  • fireWith: 傳入context和參數(shù),觸發(fā)隊(duì)列

  • fire: 傳入?yún)?shù)觸發(fā)對(duì)象,context是回調(diào)對(duì)象

  • 源碼解析

    $.Callback()方法內(nèi)部定義了多個(gè)局部變量和方法,用于記錄回調(diào)對(duì)象的狀態(tài)和函數(shù)隊(duì)列等,返回self,在self實(shí)現(xiàn)了上述回調(diào)對(duì)象的方法,用戶只能通過(guò)self提供的方法來(lái)更改回調(diào)對(duì)象。這樣的好處是保證除了self之外,沒(méi)有其他修改回調(diào)對(duì)象的狀態(tài)和隊(duì)列的途徑。

    其中,firingIndex為當(dāng)前觸發(fā)函數(shù)在隊(duì)列中的索引,list是回調(diào)函數(shù)隊(duì)列,memory記錄上次觸發(fā)的參數(shù),當(dāng)回調(diào)對(duì)象實(shí)例化時(shí)傳入memory時(shí)會(huì)用到,queue保存各個(gè)callback執(zhí)行時(shí)的context和傳入的參數(shù)。self.fire(args)實(shí)際是self.fireWith(this,args)self.fireWith內(nèi)部則調(diào)用了在Callbacks定義的局部函數(shù)fire

     ...
     // 以下變量和函數(shù) 外部無(wú)法修改,只能通過(guò)self暴露的方法去修改和訪問(wèn)
     var // Flag to know if list is currently firing
     firing,
    
     // Last fire value for non-forgettable lists
     // 保存上一次觸發(fā)callback的參數(shù),調(diào)用add之后并用該參數(shù)觸發(fā)
     memory,
    
     // Flag to know if list was already fired
     fired,
    
     // Flag to prevent firing
     // locked==true fire無(wú)效 若memory非空則同時(shí)add無(wú)效
     locked,
    
     // Actual callback list
     // callback函數(shù)數(shù)組
     list = [],
    
     // Queue of execution data for repeatable lists
     // 保存各個(gè)callback執(zhí)行時(shí)的context和傳入的參數(shù)
     queue = [],
    
     // Index of currently firing callback (modified by add/remove as needed)
     // 當(dāng)前正觸發(fā)callback的索引
     firingIndex = -1,
    
     // Fire callbacks
     fire = function() {
     ...
     },
     
     // Actual Callbacks object
     self = {
     // Add a callback or a collection of callbacks to the list
     add: function() {
     ...
     },
     ...
     // Call all callbacks with the given context and arguments
     fireWith: function( context, args ) {
     if ( !locked ) {
     args = args || [];
     args = [ context, args.slice ? args.slice() : args ]; // :前為args是數(shù)組,:后是string
     queue.push( args );
     if ( !firing ) {
     fire();
     }
     }
     return this;
     },
    
     // Call all the callbacks with the given arguments
     fire: function() {
     self.fireWith( this, arguments );
     return this;
     },
     ...
     }

    通過(guò)self.add添加函數(shù)到回調(diào)隊(duì)列中,代碼如下。先判斷是否memory且非正在觸發(fā),如果是則將fireIndex移動(dòng)至回調(diào)隊(duì)列的末尾,并保存memory。接著使用立即執(zhí)行函數(shù)表達(dá)式實(shí)現(xiàn)add函數(shù),在該函數(shù)內(nèi)遍歷傳入的參數(shù),進(jìn)行類型判斷后決定是否添加到隊(duì)列中,如果回調(diào)對(duì)象有unique標(biāo)志,則還要判斷該函數(shù)在隊(duì)列中是否已存在。如果回調(diào)對(duì)象有memory標(biāo)志,添加完畢之后還會(huì)觸發(fā)fire,執(zhí)行新添加的函數(shù)。

     add: function() {
     if ( list ) {
    
     // If we have memory from a past run, we should fire after adding
     // 如果memory非空且非正在觸發(fā),在queue中保存memory的值,說(shuō)明add后要執(zhí)行fire
     // 將firingIndex移至list末尾 下一次fire從新add進(jìn)來(lái)的函數(shù)開(kāi)始
     if ( memory && !firing ) {
     firingIndex = list.length - 1;
     queue.push( memory );
     }
    
     ( function add( args ) {
     jQuery.each( args, function( _, arg ) {
     // 傳參方式為add(fn)或add(fn1,fn2)
     if ( jQuery.isFunction( arg ) ) {
     /**
     * options.unique==false
     * 或
     * options.unique==true&&self中沒(méi)有arg
     */
     if ( !options.unique || !self.has( arg ) ) {
     list.push( arg );
     }
     } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
     // 傳參方式為add([fn...]) 遞歸
     // Inspect recursively
     add( arg );
     }
     } );
     } )( arguments ); //arguments為參數(shù)數(shù)組 所以add的第一步是each遍歷
    
     //添加到list后若memory真則fire,此時(shí)firingIndex為回調(diào)隊(duì)列的最后一個(gè)函數(shù)
     if ( memory && !firing ) {
     fire();
     }
     }
     return this;
     }

    firefireWith方法內(nèi)部實(shí)際調(diào)用了局部函數(shù)fire,其代碼如下。觸發(fā)時(shí),需要更新firedfiring,表示已觸發(fā)和正在觸發(fā)。通過(guò)for循環(huán)執(zhí)行隊(duì)里中的函數(shù)。結(jié)束循環(huán)后,將firingIndex更新為-1,表示下次觸發(fā)從隊(duì)列中的第一個(gè)函數(shù)開(kāi)始。遍歷在fireWith中更新過(guò)的queuequeue是保存數(shù)組的數(shù)組,每個(gè)數(shù)組的第一個(gè)元素是context,第二個(gè)元素是參數(shù)數(shù)組。執(zhí)行函數(shù)時(shí)要是否返回false且回調(diào)對(duì)象有stopOnFalse標(biāo)志,如果是則停止觸發(fā)。

    // Fire callbacks
     fire = function() {
    
     // Enforce single-firing
     // 執(zhí)行單次觸發(fā)
     locked = locked || options.once;
    
     // Execute callbacks for all pending executions,
     // respecting firingIndex overrides and runtime changes
     // 標(biāo)記已觸發(fā)和正在觸發(fā)
     fired = firing = true;
     // 循環(huán)調(diào)用list中的回調(diào)函數(shù)
     // 循環(huán)結(jié)束之后 firingIndex賦-1 下一次fire從list的第一個(gè)開(kāi)始 除非firingIndex被修改過(guò)
     // 若設(shè)置了memory,add的時(shí)候會(huì)修改firingIndex并調(diào)用fire
     // queue在fireWith函數(shù)內(nèi)被更新,保存了觸發(fā)函數(shù)的context和參數(shù)
     for ( ; queue.length; firingIndex = -1 ) {
     memory = queue.shift();
     while ( ++firingIndex < list.length ) { 
    
     // Run callback and check for early termination
     // memory[0]是content memory[1]是參數(shù)
     if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
     options.stopOnFalse ) {
     
     // Jump to end and forget the data so .add doesn't re-fire
     // 當(dāng)前執(zhí)行函數(shù)范圍false且options.stopOnFalse==true 直接跳至list尾 終止循環(huán)
     firingIndex = list.length;
     memory = false;
     }
     }
     }
    
     // 沒(méi)設(shè)置memory時(shí)不保留參數(shù)
     // 設(shè)置了memory時(shí) 參數(shù)仍保留在其中
     // Forget the data if we're done with it
     if ( !options.memory ) {
     memory = false;
     }
    
     firing = false;
    
     // Clean up if we're done firing for good
     if ( locked ) {
    
     // Keep an empty list if we have data for future add calls
     if ( memory ) {
     list = [];
    
     // Otherwise, this object is spent
     } else {
     list = "";
     }
     }
     },

    聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    jQuery源碼之Callbacks的學(xué)習(xí)

    jQuery源碼之Callbacks的學(xué)習(xí):這篇文章主要介紹了關(guān)于jQuery源碼之Callbacks的學(xué)習(xí),有著一定的參考價(jià)值,現(xiàn)在分享給大家,有需要的朋友可以參考一下jQuery源碼學(xué)習(xí)之CallbacksjQuery的ajax、deferred通過(guò)回調(diào)實(shí)現(xiàn)異步,其實(shí)現(xiàn)核心是Callbacks。使用方法使用首先要先新建一個(gè)實(shí)例對(duì)
    推薦度:
    • 熱門焦點(diǎn)

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 久久久久免费精品国产小说 | 国产最新精品视频 | 亚洲一区 中文字幕 | 国产 高清 在线 | 国产精品毛片va一区二区三区 | 一级不卡毛片免费 | 欧美wwww | 日韩在线视频免费观看 | 一级毛片在线看在线播放 | 欧美日韩大尺码免费专区 | 日韩欧美精品综合一区二区三区 | 九九久久国产 | 欧美色综合图区 | 欧美性猛交xxx乱大交 | 国产精品成人一区二区三区 | 国产网站视频 | 国产 日韩 欧美在线 | 国产91精品久久久久久久 | 久久91精品国产91久久户 | 日韩精品一二三区 | 国产精彩视频在线观看 | 日本国产最新一区二区三区 | 午夜日韩在线 | 欧美久久天天综合香蕉伊 | 免费国产叼嘿视频大全网站 | 国产精品va在线观看无 | 精品日韩一区 | 亚洲一区二区三区久久久久 | 久久久成人影院 | 欧美极品一区 | 亚洲欧美一区二区三区九九九 | 欧美国产亚洲一区二区三区 | 精品国产一区二区三区香蕉 | www.九九热 | 国产精品久久成人影院 | 欧美日韩精品一区二区在线播放 | 国产aⅴ精品一区二区三区久久 | 亚洲综合图片小说区热久久 | 久久精品一区二区三区四区 | 国产网站免费在线观看 | 制服丝袜中文字幕在线 |