目錄
jQuery源碼學習之Callbacks
使用方法
fireWith
首頁 web前端 js教程 jQuery源碼之Callbacks的學習

jQuery源碼之Callbacks的學習

Jul 09, 2018 am 10:57 AM
javascript jquery

這篇文章主要介紹了關於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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前 By 尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

jQuery引用方法詳解:快速上手指南 jQuery引用方法詳解:快速上手指南 Feb 27, 2024 pm 06:45 PM

jQuery引用方法詳解:快速上手指南

jQuery中如何使用PUT請求方式? jQuery中如何使用PUT請求方式? Feb 28, 2024 pm 03:12 PM

jQuery中如何使用PUT請求方式?

jQuery如何移除元素的height屬性? jQuery如何移除元素的height屬性? Feb 28, 2024 am 08:39 AM

jQuery如何移除元素的height屬性?

jQuery小技巧:快速修改頁面所有a標籤的文本 jQuery小技巧:快速修改頁面所有a標籤的文本 Feb 28, 2024 pm 09:06 PM

jQuery小技巧:快速修改頁面所有a標籤的文本

使用jQuery修改所有a標籤的文字內容 使用jQuery修改所有a標籤的文字內容 Feb 28, 2024 pm 05:42 PM

使用jQuery修改所有a標籤的文字內容

了解jQuery中eq的作用及應用場景 了解jQuery中eq的作用及應用場景 Feb 28, 2024 pm 01:15 PM

了解jQuery中eq的作用及應用場景

如何判斷jQuery元素是否具有特定屬性? 如何判斷jQuery元素是否具有特定屬性? Feb 29, 2024 am 09:03 AM

如何判斷jQuery元素是否具有特定屬性?

PHP常用的檔案操作函數總結 PHP常用的檔案操作函數總結 Apr 03, 2024 pm 02:52 PM

PHP常用的檔案操作函數總結

See all articles