Maison  >  Article  >  interface Web  >  En savoir plus sur les rappels du code source jQuery

En savoir plus sur les rappels du code source jQuery

不言
不言original
2018-07-09 10:57:341362parcourir

Cet article présente principalement l'apprentissage des rappels du code source de jQuery. Il a une certaine valeur de référence. Maintenant, je le partage avec tout le monde. Les amis dans le besoin peuvent s'y référer

Rappels d'apprentissage du code source de jQuery

Les

et ajax de jQuery sont implémentés de manière asynchrone via des rappels, et le cœur de son implémentation est deferred. Callbacks

Méthode d'utilisation

Pour l'utiliser, vous devez d'abord créer un nouvel objet instance. Lors de la création, vous pouvez passer le paramètre

pour indiquer les restrictions sur les objets de rappel. Les valeurs facultatives sont les suivantes. flags

  •  : Arrêter le déclenchement lorsque la fonction dans la file d'attente des fonctions de rappel revient stopOnFalse false

  •  : La file d'attente des fonctions de rappel ne peut être déclenché qu'une seule fois once

  •  : enregistre la valeur transmise depuis la dernière file d'attente de déclenchement. La fonction nouvellement ajoutée à la file d'attente utilise la valeur enregistrée comme paramètre et est exécutée immédiatement. memory

  •  : Les fonctions de la file d'attente des fonctions sont toutes uniques 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

fournit une série de méthodes d'instance pour utilisez la file d'attente et affichez l'état des objets de rappel. Callbacks

  •  : Ajouter une fonction à la file d'attente de rappel, qui peut être une fonction ou un tableau de fonctions add

  •  : Supprimez-le de la file d'attente de rappel Spécifiez la fonction remove

  •  : Déterminez si une certaine fonction existe dans la file d'attente de rappel has

  •  : Effacer la file d'attente de rappel empty

  •  : Désactivez l'ajout de fonctions et de files d'attente de déclenchement, l'effacement de la file d'attente de rappel et la dernière valeur transmise disable

  •  : Déterminer si l'objet de rappel a été Désactivé disabled

  •  : Désactiver lock, si la mémoire n'est pas vide, l'ajout sera invalide en même temps fire

  •  : Déterminer s'il est appelé lockedlock

  •  : Passer fireWith et les paramètres, déclencher la file d'attente context

  •  : Passer les paramètres pour déclencher l'objet, fire est l'objet de rappel context

Analyse du code source

définit plusieurs variables et méthodes locales à l'intérieur, qui sont utilisées pour enregistrer l'état et les fonctions de l'objet de rappel, etc., renvoie

Les méthodes d'objet de rappel ci-dessus sont implémentées dans $.Callback(). modifiez l'objet de rappel via les méthodes fournies par self. L'avantage de ceci est de garantir qu'il n'y a pas d'autre moyen de modifier l'état et la file d'attente de l'objet de rappel que self. selfself Parmi eux,

est l'index de la fonction de déclenchement actuelle dans la file d'attente,

est la file d'attente de la fonction de rappel, firingIndex enregistre les paramètres du dernier déclencheur et est transmis lorsque le L'objet de rappel est instancié list Il sera utilisé lorsque memory enregistre le contexte et les paramètres entrants lors de l'exécution de chaque rappel. memory est en fait queue, et en interne self.fire(args) appelle la fonction locale self.fireWith(this,args) définie dans self.fireWith. Callbacksfire

Ajoutez une fonction à la file d'attente de rappel via
    ...
    // 以下变量和函数 外部无法修改,只能通过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;
            },
            ...
        }
, le code est le suivant. Déterminez d'abord si

n'est pas déclenché. Si tel est le cas, déplacez self.add à la fin de la file d'attente de rappel et enregistrez memory. Utilisez ensuite l'expression de fonction d'exécution immédiate pour implémenter la fonction d'ajout, parcourez les paramètres entrants dans la fonction et déterminez s'il faut l'ajouter à la file d'attente après avoir effectué le jugement de type. Si l'objet de rappel a la marque fireIndex, cela est également nécessaire. pour juger si la fonction est dans la file d'attente. Existe-t-elle déjà ? Si l'objet de rappel porte la marque memory, unique sera déclenché une fois l'ajout terminé pour exécuter la fonction nouvellement ajoutée. Les méthodes memoryfire

            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 && !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中没有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为参数数组 所以add的第一步是each遍历

                    //添加到list后若memory真则fire,此时firingIndex为回调队列的最后一个函数
                    if ( memory && !firing ) {
                        fire();
                    }
                }
                return this;
            }
et

appellent en fait la fonction locale fire, et le code est le suivant. Lorsqu'ils sont déclenchés, fireWith et fire doivent être mis à jour pour indiquer qu'ils ont été déclenchés et sont en cours de déclenchement. Exécutez les fonctions dans la file d'attente via une boucle for. Après avoir terminé la boucle, mettez à jour fired à -1, indiquant que le prochain déclencheur démarrera à partir de la première fonction de la file d'attente. Parcourez le firing mis à jour dans firingIndex, fireWith est le tableau qui enregistre le tableau, le premier élément de chaque tableau est queue et le deuxième élément est le tableau de paramètres. Lors de l'exécution de la fonction, il est nécessaire de vérifier si queue est renvoyé et si l'objet de rappel porte la marque context. Si c'est le cas, arrêtez le déclenchement. falsestopOnFalse

// 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't re-fire
                        // 当前执行函数范围false且options.stopOnFalse==true 直接跳至list尾 终止循环
                        firingIndex = list.length;
                        memory = false;
                    }
                }
            }

            // 没设置memory时不保留参数
            // 设置了memory时 参数仍保留在其中
            // 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 = "";
                }
            }
        },

Ce qui précède est l'intégralité du contenu de cet article. J'espère qu'il sera utile à l'étude de chacun. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois !

Recommandations associées :

Introduction à la boucle for asynchrone js


jQuery-Ajax demande des données Json et les charge sur le page d'accueil

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn