首頁 > web前端 > js教程 > 主體

jQuery源碼之Callbacks的學習

不言
發布: 2018-07-09 10:57:34
原創
1300 人瀏覽過

這篇文章主要介紹了關於jQuery源碼之Callbacks的學習,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

jQuery源碼學習之Callbacks

jQuery的ajaxdeferred透過回呼實現非同步,其實作核心是Callbacks

使用方法

使用首先要先新建一個實例物件。建立時可以傳入參數flags,表示對回呼物件的限制,可選值如下表示。

  • stopOnFalse:回呼函數佇列中的函數返回false時停止觸發

  • ##once
:回呼函數佇列只能被觸發一次

    memory
  • :記錄上一次觸發佇列傳入的值,並新加入到佇列中的函數使用記錄值作為參數,並立即執行。

  • unique
  • :函數佇列中函數都是唯一的

    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
  • 提供了一系列實例方法來操作佇列和查看回呼物件的狀態。

  • add
  • : 新增函數到回呼佇列中,可以是函數或函數陣列

  • #remove
  • : 從回呼佇列中刪除指定函數

  • has
  • : 判斷回呼佇列裡是否存在某個函數

  • empty
  • : 清空回呼佇列

    disable

    : 禁止新增函數和觸發佇列,清空回呼佇列和上一個傳入的值
  • disabled: 判斷回呼物件是否被停用

  • lock: 停用fire ,若memory非空則同時add無效

  • locked: 判斷是否呼叫了lock

fireWith

: 傳入

context和參數,觸發隊列##fire: 傳入參數觸發對象,context是回呼對象

原始碼解析$.Callback()方法內部定義了多個局部變數和方法,用於記錄回調物件的狀態和函數佇列等,傳回self,在self實現了上述回呼物件的方法,使用者只能透過self 提供的方法來更改回呼物件。這樣的好處是保證除了self之外,沒有其他修改回呼物件的狀態和佇列的途徑。 其中,firingIndex為目前觸發函數在佇列中的索引,list是回呼函數佇列,memory記錄上次觸發的參數,當回呼物件實例化時傳入

memory

時會用到,queue儲存各個callback執行時的context和傳入的參數。 self.fire(args)實際上是self.fireWith(this,args)self.fireWith內部則呼叫了在Callbacks定義的局部函數fire<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"> ... // 以下变量和函数 外部无法修改,只能通过self暴露的方法去修改和访问 var // Flag to know if list is currently firing firing, // Last fire value for non-forgettable lists // 保存上一次触发callback的参数,调用add之后并用该参数触发 memory, // Flag to know if list was already fired fired, // Flag to prevent firing // locked==true fire无效 若memory非空则同时add无效 locked, // Actual callback list // callback函数数组 list = [], // Queue of execution data for repeatable lists // 保存各个callback执行时的context和传入的参数 queue = [], // Index of currently firing callback (modified by add/remove as needed) // 当前正触发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是数组,:后是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; }, ... }</pre><div class="contentsignin">登入後複製</div></div>透過

self.add

新增函數到回呼佇列中,程式碼如下。先判斷是否memory且非正在觸發,如果是則將fireIndex移到回呼佇列的結尾,並儲存memory。接著使用立即執行函數表達式實現add函數,在該函數內遍歷傳入的參數,進行類型判斷後決定是否添加到隊列中,如果回調對像有unique標誌,則還要判斷該函數在隊列中是否已存在。如果回呼物件有memory標誌,新增完畢之後還會觸發fire,執行新新增的函數。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"> add: function() { if ( list ) { // If we have memory from a past run, we should fire after adding // 如果memory非空且非正在触发,在queue中保存memory的值,说明add后要执行fire // 将firingIndex移至list末尾 下一次fire从新add进来的函数开始 if ( memory &amp;&amp; !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&amp;&amp;self中没有arg */ if ( !options.unique || !self.has( arg ) ) { list.push( arg ); } } else if ( arg &amp;&amp; arg.length &amp;&amp; jQuery.type( arg ) !== &quot;string&quot; ) { // 传参方式为add([fn...]) 递归 // Inspect recursively add( arg ); } } ); } )( arguments ); //arguments为参数数组 所以add的第一步是each遍历 //添加到list后若memory真则fire,此时firingIndex为回调队列的最后一个函数 if ( memory &amp;&amp; !firing ) { fire(); } } return this; }</pre><div class="contentsignin">登入後複製</div></div>firefireWith方法內部實際呼叫了局部函數fire,其程式碼如下。觸發時,需要更新firedfiring,表示已觸發和正在觸發。透過for迴圈執行隊裡中的函數。結束循環後,將

firingIndex

更新為-1,表示下次觸發從佇列中的第一個函數開始。遍歷在

fireWith

中更新過的

queue

queue

是保存數組的數組,每個數組的第一個元素是context# ,第二個元素是參數數組。執行函數時要是否回傳
false

且回呼物件有
// Fire callbacks
        fire = function() {

            // Enforce single-firing
            // 执行单次触发
            locked = locked || options.once;

            // Execute callbacks for all pending executions,
            // respecting firingIndex overrides and runtime changes
            // 标记已触发和正在触发
            fired = firing = true;
            // 循环调用list中的回调函数
            // 循环结束之后 firingIndex赋-1 下一次fire从list的第一个开始 除非firingIndex被修改过
            // 若设置了memory,add的时候会修改firingIndex并调用fire
            // queue在fireWith函数内被更新,保存了触发函数的context和参数
            for ( ; queue.length; firingIndex = -1 ) {
                memory = queue.shift();
                while ( ++firingIndex < list.length ) { 

                    // Run callback and check for early termination
                    // memory[0]是content memory[1]是参数
                    if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
                        options.stopOnFalse ) {
                        
                        // Jump to end and forget the data so .add doesn&#39;t re-fire
                        // 当前执行函数范围false且options.stopOnFalse==true 直接跳至list尾 终止循环
                        firingIndex = list.length;
                        memory = false;
                    }
                }
            }

            // 没设置memory时不保留参数
            // 设置了memory时 参数仍保留在其中
            // Forget the data if we&#39;re done with it
            if ( !options.memory ) {
                memory = false;
            }

            firing = false;

            // Clean up if we&#39;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 = "";
                }
            }
        },
登入後複製

  

###以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP中文網! ######相關推薦:#########js 非同步for循環的介紹################jQuery-Ajax請求Json資料並載入在前端頁面##########

以上是jQuery源碼之Callbacks的學習的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!