Maison > interface Web > js tutoriel > le corps du texte

Explication détaillée des rappels dans le code source jQuery Analysis_jquery

WBOY
Libérer: 2016-05-16 16:09:47
original
1294 Les gens l'ont consulté

L'essence du code met en évidence le concept de séquence et d'ordre, en particulier en JavaScript - après tout, JavaScript est un moteur à thread unique.

Javascript a les caractéristiques de la programmation fonctionnelle, et en raison du moteur JavaScript monothread, nos fonctions doivent toujours être exécutées de manière ordonnée. Un excellent code découpe souvent les fonctions dans leurs propres modules, puis les exécute sous certaines conditions. Puisque ces fonctions sont exécutées de manière ordonnée, pourquoi ne pas écrire un objet de gestion unifié pour nous aider à gérer ces fonctions - donc, les rappels (fonctions de rappel). ) sont nés.

Que sont les rappels

Javascript regorge de programmation fonctionnelle. Par exemple, le window.onload le plus simple accepte une fonction. Ce qui est triste, c'est que window.onload ne peut recevoir qu'une seule fonction si elle est affectée directement. exécuter dans onload, Ensuite, nous devons écrire le code suivant :

Copier le code Le code est le suivant :

fonction a(elem) {
                elem.innerHTML = 'Je suis la fonction a, je souhaite changer la structure HTML de l'élément';
        };
         fonction b(elem) {
                elem.innerHTML = 'Ma fonction b, je souhaite changer le style de l'élément';
>
          window.onload = function () {
               var elem = document.getElementById('test');
un(elem);
              b(elem);
        };

L'intention initiale de la fonction de rappel est de s'appuyer sur une telle chose. Elle ne nous permet plus de disperser ces fonctions, mais d'organiser ces fonctions de manière unifiée. Comme vous pouvez le voir, nous voulons faire deux choses pour un élément dans window.onload : d'abord changer la structure HTML, puis changer le style du HTML. Les deux fonctions opèrent également sur un Elément, et l'exécution finale de ces deux fonctions s'effectue dans l'ordre. Alors pourquoi ne pas écrire un objet comme celui-ci pour gérer ces fonctions. Bien sûr, ce n’est que la signification la plus élémentaire de la fonction de rappel. Nous avons besoin de plus qu’un simple objet de fonction de rappel, nous avons besoin d’une fonction de rappel plus puissante. Eh bien, ce n'est qu'un simple cas d'utilisation, je peux donc vous dire ce que cette fonction de rappel peut faire en plus d'exécuter les fonctions une par une.

L'essence des rappels est de contrôler l'exécution ordonnée des fonctions. Javascript est un moteur monothread, ce qui signifie qu'un seul code JavaScript s'exécute en même temps - même Ajax et setTimeout. Ces deux fonctions semblent asynchrones, mais ce n'est pas le cas. Lorsque le navigateur exécute du code javascript, ces codes seront placés dans une file d'attente de manière ordonnée. Lorsque vous exécutez Ajax, le navigateur les poussera dans la file d'attente de codes. Le navigateur prend le code un par un dans la file d'attente de code lors du traitement du code JavaScript - Rappels, destinés à ce moteur monothread.

Bien sûr, ce que nous voulons, c'est plus qu'un simple objet outil - dans le code source de jQuery, les rappels fournissent la gestion de base d'un ensemble de fonctions, constituent la base de Deferred (file d'attente asynchrone) et servent également de file d'attente. (file d'attente de synchronisation). Deferred est utilisé pour lisser/aplatir la programmation pyramidale (un grand nombre de fonctions de rappel imbriquées, telles que le code en Ajax qui doit être exécuté en fonction du code de retour de la requête et les lecteurs de file d'attente jQuery.animate (moteur d'animation).

Alors écrivons un rappel.

Modèle de rappels

Tableau :
Puisque nos Callbacks veulent accepter une série de fonctions, nous devons avoir un conteneur. Nous pouvons utiliser un tableau et pousser chaque fonction dans le tableau Lorsqu'elle doit être exécutée, bouclez les éléments du tableau à exécuter.

Modèle de travail :

Ces rappels doivent être très puissants. Ce n'est pas aussi simple que de pousser une fonction puis de l'exécuter.
once : toutes les fonctions de l'objet Callbacks actuel ne seront exécutées qu'une seule fois et seront publiées après l'exécution. Nous pouvons fournir une solution stable et efficace aux utilisateurs qui utilisent l'objet Callbacks pour garantir que la fonction ne sera exécutée qu'une seule fois et ne le sera pas. être exécuté à nouveau, ce qui stabilise les threads de ces fonctions.
auto : modèle d'exécution automatique. C'est un modèle intéressant. Certaines fonctions dépendent de la fonction de la couche précédente. Par exemple, l'exécution de la fonction b dépend de la fonction a. Ensuite, nous fournissons un modèle d'exécution automatique : après la première exécution de ce Callbacks, chaque fois qu'elle est ajoutée. Lorsque la fonction atteint les rappels, elle exécute automatiquement les fonctions ajoutées dans le passé et transmet les dernières données de paramètre données aux fonctions passées. Cela élimine le besoin de déclenchements répétés entre ces fonctions dépendantes à partir des rappels. un modèle intéressant.
once&auto : nous pouvons le rendre plus puissant et travailler avec les modèles once et auto en même temps, c'est-à-dire : chaque fois qu'une fonction est ajoutée aux rappels, les fonctions passées seront exécutées, puis ces fonctions passées seront libérées, et les fonctions continueront à être ajoutées la prochaine fois. À ce moment-là, ces fonctions du passé ne seront plus exécutées car le modèle une fois les a publiées.

API :

add(function) - Ajoutez une (ou plusieurs) fonctions à l'objet Callbacks : Bien sûr, si vous n'ajoutez pas de fonctions et que vous êtes simplement curieux de jeter un œil aux Callbacks, nous vous laissons continuer à vous amuser - nous ne lancerons pas d'exception car ce n'est pas quelque chose pour lequel nous sommes bons.
remove(function) - supprime une fonction dans un rappel : maintenant que nous l'avons ajoutée, nous devrions également fournir un plan pour le regretter. Nous sommes très accessibles et tolérons tout ce que d'autres ont fait dans le passé.
has(function) - Détermine si les rappels contiennent une fonction : Oh ? Vous ne savez pas si vous devez inclure cette fonction, mais vous l'avez ajoutée en premier lieu ! Pourquoi es-tu si négligent ? Mais puisque vous me l'avez demandé, je vais quand même vous dire si les rappels contiennent cette fonction. Je sais que vous êtes très occupé et que vous ne pouvez pas tout mémoriser et déterminer.
empty() - Rappels vides : ces fonctions ont-elles perdu leur sens pour vous ? Quoi? Vous n’en voulez plus après son exécution ? Alors tu aimerais pouvoir l'effacer ? Eh bien, pour des raisons de mémoire, je tolère toujours votre demande.
Disable() - Désactiver un rappel : afin de maintenir une existence stable avec le code des autres, j'ai choisi le sacrifice de soi - oui, cette méthode peut désactiver les rappels, les désactiver complètement, comme s'ils n'existaient pas auparavant.
désactivé () - Détermine si les rappels ont été désactivés : si vous ne croyez toujours pas si les rappels sont vraiment sacrifiés, cette méthode peut vous apporter une tranquillité d'esprit.
lock(boolean) - Verrouillez cet objet Callbacks : vous craignez qu'il soit instable, mais vous ne souhaitez pas l'abandonner. Lock est une bonne méthode. Il reçoit un paramètre booléen pour indiquer si l'objet doit être verrouillé. Bien sûr, il n'a aucun paramètre. Permet de déterminer si les rappels sont verrouillés.
fire(data) - Exécuter la fonction dans ce rappel : tout ce que nous faisons n'est-il pas destiné au sort de l'exécution en ce moment ? Les paramètres deviendront les paramètres de ces fonctions qui doivent être exécutées.
fireWith(context,data) - Exécutez la fonction dans Callbacks et spécifiez le contexte. Dans fire(), le Context de toutes les fonctions sont des objets Callbacks, et fireWidth() vous permet de redéfinir le contexte de ces fonctions à exécuter. Quelle que soit la gratuité de la programmation, Callbacks considère tout pour vous.
Fired() - Déterminez si cet objet Callbacks a été exécuté dans le passé : nous pensons que la plupart du temps, vous ne savez pas ce que vous avez fait dans le passé, mais nous enregistrons tout ce que vous faites si vous avez exécuté cet objet Callbacks. le passé, alors vous ne pouvez jamais le nier, car nous savons si vous avez exécuté ces rappels dans le passé.

Mise en œuvre du module de base

Mise en œuvre simple :
Commençons par simplement implémenter un rappel :

Copier le code Le code est le suivant :

(fonction (fenêtre, non définie) {
            var Rappels = function () {
//Protégez ces variables privées via des fermetures
                   var list = [],//Liste des fonctions de rappel
Viré ; // Avez-vous exécuté
//Renvoie un objet Callbakcs de fermeture
                   revenir {
                         ajouter : fonction (fn) {
//Lorsque les rappels sont supprimés, la liste n'est pas définie
Si (liste) {
//Ajouter une fonction de rappel
                                 list.push(fn);
//Rappels de chaîne de support
                                                                                                          }                                                                                         renvoie ceci ;                     },
fireWith : fonction (contexte, données) {
//Déclenchez la fonction de rappel et spécifiez le contexte
Si (liste) {
viré = vrai ;
pour (var i = 0, len = list.length; i < len; i ) {
//Lorsqu'une fonction dans Callbacks renvoie false, arrêtez l'exécution ultérieure de Callbacks
Si (list[i].apply(context, data) === false)
pause;
                                                                                                   }                                                                                                           }                                                                                         retournez ceci ;                     },
Feu : fonction() {
//Fonction de rappel de déclenchement
//Appelle fireWith et précise le contexte
Renvoyez this.fireWith(this, arguments);
                    },
                      vide : fonction () {
//Effacer la liste
                                                                                                                                                   if (list)//Lorsque ces rappels sont supprimés, les rappels ne devraient plus pouvoir continuer à être utilisés
liste = [];
                                                                                        retournez ceci ;                     },
                           désactiver : fonction () {
//Abandonnez cet objet Callbacks et la liste de fonctions de rappel suivante ne sera plus exécutée
                         list = undefined;
                                                                                        retournez ceci ;                     },
                       désactivé : fonction () {//Détecter si ces rappels ont été désactivés
//Convertir en booléen et renvoyer
Retour !list;
                    },
                     déclenché : fonction () {//Si ces rappels ont été exécutés
                                                                                                                                                                                                                }
                };
            };
// S'inscrire à la fenêtre
               window.Callbacks = Rappels ;
         }(fenêtre));



Alors testons ces rappels :

Copier le code Le code est le suivant :

        var test = new Callbacks();
         test.add(fonction (valeur) {
                console.log('Fonction 1, la valeur est : ' valeur);
        });
         test.add(fonction (valeur) {
​​​​​​ console.log('Fonction 2, la valeur est :' value);
        });
​​​​ test.fire('Voici la valeur de la fonction 1 et de la fonction 2');
console.log('Vérifiez si la fonction a été exécutée :' test.fired());
         test.disable();//Abandonner ces rappels
console.log('Vérifiez si la fonction est abandonnée :' test.disabled());
         test.add(function () {
console.log('Ajouter une troisième fonction, cette fonction ne doit pas être exécutée');
        });
         test.fire();

Ouvrez la console du navigateur et nous pouvons voir que les résultats d'exécution sont normaux.

implémentation unique et automatique (en mémoire)

une fois :
Once permet à la fonction de ce rappel de s'exécuter une fois, puis de ne plus s'exécuter. Le principe est très simple. Dans le code ci-dessus, nous pouvons voir qu'il existe une liste de variables qui prend le relais de la liste des fonctions, il suffit donc d'effacer les codes qui ont été exécutés dans le passé. Nous utilisons une variable globale pour enregistrer le modèle d'exécution actuel, s'il s'agit d'un modèle unique, invalidez simplement la liste dans fireWith() :

.

Copier le code Le code est le suivant :

(fonction (fenêtre, non définie) {
            var Rappels = fonction (une fois) {
//Protégez ces variables privées via des fermetures
                   var list = [],//Liste des fonctions de rappel
Viré ; // Avez-vous exécuté
//Renvoie un objet Callbakcs de fermeture
                   revenir {
//...Omettre du code
fireWith : fonction (contexte, données) {
//Déclenchez la fonction de rappel et spécifiez le contexte
Si (liste) {
viré = vrai ;
pour (var i = 0, len = list.length; i < len; i ) {
//Lorsqu'une fonction dans Callbacks renvoie false, arrêtez l'exécution ultérieure de Callbacks
Si (list[i].apply(context, data) === false)
pause;
                                                                                                   }                                                                                                           } //Si le modèle once est configuré, la variable globale once est vraie et la liste est réinitialisée
Si (une fois) liste = non défini ;
                                                                                        retournez ceci ;                  }
//...Omettre du code
                };
            };
// S'inscrire à la fenêtre
               window.Callbacks = Rappels ;
         }(fenêtre));

auto :

Le modèle auto (mémoire) porte le nom de la mémoire dans jQuery. Au début, j'ai été dérouté par ce nom. Après avoir soigneusement examiné son utilisation, j'ai décidé de le changer en auto - sa fonction est "après le premier incendie()". , la "fonction add() suivante s'exécute automatiquement" peut être utilisée dans les situations suivantes : après avoir ajouté un ensemble de fonctions aux rappels, et vous devez temporairement ajouter une fonction, puis exécutez immédiatement la fonction nouvellement ajoutée - il faut dire que pour le commodité d'utilisation, ce modèle devient un peu difficile à comprendre. L'implémentation consiste à déterminer s'il s'agit d'un modèle automatique lors de add(). S'il s'agit d'un modèle automatique, exécutez cette fonction. Cependant, nous devons l'exécuter automatiquement après le premier fire(). Les rappels qui n'ont pas été déclenchés() ne doivent pas être automatiquement exécutés. De plus, après chaque exécution automatique, les derniers paramètres utilisés doivent être transmis à cette fonction exécutée automatiquement.

Peut-être penserez-vous au code suivant :

Copier le code Le code est le suivant :

(fonction (fenêtre, non définie) {
            var Rappels = fonction (une fois, auto) {
              var liste = [],
viré,
lastData;//Enregistrer les paramètres de la dernière exécution
                   revenir {
                         ajouter : fonction (fn) {
Si (liste) {
                                 list.push(fn);
​​​​​​​​​​​​ //Le dernier paramètre utilisé est passé, et le Contexte est perdu ici
//Afin d'éviter que le contexte ne soit perdu ici, nous devrons peut-être également déclarer une variable pour sauvegarder le dernier Context utilisé
Si (auto) this.fire(lastData);
                                                                                                          }                                                                                         retournez ceci ;                     },
fireWith : fonction (contexte, données) {
Si (liste) {
lastData = data;// — Enregistre le dernier paramètre utilisé
viré = vrai ;
pour (var i = 0, len = list.length; i < len; i ) {
Si (list[i].apply(context, data) === false)
pause;
                                                                                                   }                                                                                                           } Si (une fois) liste = [];
                                                                                        retournez ceci ;                  }
//Une partie du code est omise
                };
            };
// S'inscrire à la fenêtre
               window.Callbacks = Rappels ;
         }(fenêtre));

Mais une utilisation plus merveilleuse est adoptée dans jQuery. L'auteur de jQuery est également fier de cette utilisation, c'est pourquoi il a nommé ce modèle mémoire - c'est-à-dire que la variable ci-dessus auto représente non seulement le mode d'exécution automatique actuel, mais sert également. comme dernier conteneur de paramètres, qui représente à la fois l'auto et la mémoire. (Le code suivant n'est pas jQuery et est écrit sur la base d'idées de code jQuery, et non de code source) :

Copier le code Le code est le suivant :

(fonction (fenêtre, non définie) {
            var Rappels = fonction (auto) {
              var liste = [],
viré,
Mémoire,//L'acteur principal est là, c'est la mémoire
coreFire = fonction (données) {
//La véritable méthode de la fonction déclencheur
Si (liste) {
                                                                                                                                   Mémoire = auto && data;//Enregistrer le dernier paramètre S'il n'est pas en mode auto, ce paramètre ne sera pas enregistré
. //Si c'est le mode auto, alors cet auto ne sera pas faux, ce sera un tableau
viré = vrai ;
pour (var i = 0, len = list.length; i < len; i ) {
Si (list[i].apply(data[0], data[1]) === false)
pause;
                                                                                                   }                                                                                                           }                     };
                   revenir {
                         ajouter : fonction (fn) {
Si (liste) {
//Ajouter une fonction de rappel
                                 list.push(fn);
//Mode d'exécution automatique, notez que si le modèle auto
//la mémoire est attribuée dans coreFire(), la valeur par défaut est false
Si (mémoire) coreFire(auto);
                                                                                                          } //Rappels de chaîne de support
                                                                                        retournez ceci ;                    },
fireWith : fonction (contexte, données) {
Si (une fois) liste = [];
//Appelez coreFire ici et convertissez les paramètres en tableau
coreFire([contexte, données]);
                                                                                        retournez ceci ;                  }
                                                                                                                                                                                                                                                               };
            };
               window.Callbacks = Rappels ;
         }(fenêtre));


Nous avons vu dans le code de l'implémentation automatique précédente que nous avions perdu le contexte. jQuery a corrigé ce bug au début de fireWith() - corrige les paramètres dans fireWith(). jQuery extrait la logique qui doit exécuter la fonction dans fireWith(). Nous l'appelons temporairement coreFire(). Dans le fireWith() d'origine, les paramètres sont fusionnés dans un tableau : le premier paramètre représente le contexte et le deuxième paramètre. Les paramètres représentent les paramètres transmis. Exécutez ensuite coreFire().


Pendant add(), jQuery n'a pas attribué de valeur à la variable auto(memory), mais a choisi d'attribuer une valeur à auto(memory) dans coreFire(), garantissant ainsi qu'elle ne sera pas activée avant le premier fire(). Exécuté automatiquement.


Comme mentionné ci-dessus, les paramètres reçus par coreFire() sont en fait un tableau. Le premier paramètre est le contexte et le deuxième paramètre est le paramètre transmis de l'extérieur. En même temps, affectez ce tableau à auto (mémoire), pour que la définition de la variable auto (si exécuter le mode automatiquement) devienne mémoire (mémoire du dernier paramètre passé).

C'est vraiment une idée géniale qui fait d'une pierre deux coups, je dois l'aimer. Je définis cela comme auto car il s'agit d'un modèle exécuté automatiquement, et en passant, les paramètres du dernier fire() sont enregistrés. La définition de jQuery en tant que mémoire peut être le soupir de l'auteur pour le travail miraculeux ici.


Quant à once&auto, il combine simplement ces deux codes. Il vous suffit de déterminer dans coreFire() que s'il est en mode automatique, puis de réinitialiser la liste sur un nouveau tableau, sinon de la définir directement sur non défini.

Code source

Ce code est écrit à la main par moi et correspond à jQuery. Certaines fonctions publiques de jQuery sont écrites. Ce n'est pas un fragment de code, il peut donc être directement référencé et exécuté.

Copier le code Le code est le suivant :

(fonction (fenêtre, non définie) {
/*
* Un objet outil de fonction de rappel. Notez que le tableau sera effacé une fois l'objet de travail terminé :
. * * Fournit un ensemble commun d'API, mais il a le modèle de travail suivant -
​​​ *Modèle d'exécution automatique : chaque ajout d'une fonction de rappel est ajouté pour exécuter automatiquement toutes les fonctions de rappel dans l'ensemble de fonctions de rappel existant, et les paramètres de cette fois sont transmis à toutes les fonctions de rappel
*
*/

//Fonction outil
var isIndexOf = Array.prototype.indexOf, //Es6
        toString = Object.prototype.toString, //Méthode Cache toString
TosLice = Array.prototype.slice, // Méthode Caches Slice
                                                                                                                                                                                                  return "object" === typeof document.getElementById ?
               isFunction = function (fn) {
                      //Il y a un problème avec la reconnaissance du DOM et du BOM sous ie
                  essayez {
Retour /^s*bfunctionb/.test("" fn);
                        } attraper (x) {
Renvoyer faux
                }
               } :
               isFunction = function (fn) { return toString.call(fn) === '[object Function]' };
;          })(),
                                                                                                                                                                                                //Le premier paramètre représente le tableau à boucler, et le deuxième paramètre est la fonction exécutée à chaque fois dans la boucle
Si (arguments.length < 2 || !isFunction(arguments[1])) return;
                       //Pourquoi la tranche n'est-elle pas valide ? ?
          var list = toSlice.call(arguments[0]),
                             fn = arguments[1],
article ;
​​​​​​while ((item = list.shift())) {//Pas de détermination directe de la longueur, accélère
// Pourquoi utiliser call ici, et Apply ne convient pas ?
                               // Terminé - le deuxième paramètre de apply doit être un objet tableau (il n'y a aucune vérification si l'apparence d'un tableau est possible, et l'appel n'a pas cette exigence)
                                                                        //apply est décrit comme suit : Si argArray (le deuxième paramètre) n'est pas un tableau valide ou n'est pas un objet d'arguments, une TypeError sera provoquée.
                           fn.call(window, item);
            }
},
inArray = function () { //Détecte si le tableau contient un élément et renvoie l'index de l'élément
                                                                                                                                                                // Pré-compilation
                 return isIndexOf ? (array, elem, i) {
Si (tableau)
                          return isIndexOf.call(array, elem, i);
                    return -1 ;
               } : fonction (elem, array, i) {
              var len;
                    if (tableau) {
                    len = tableau.longueur;
                    je = je ? je &Lt ; 0 ? Math.max(0, len i) : i : 0;
                    pour (; je < len; je ) {
                        if (i in array && array[i] === elem) {
                            reviens-moi ;
                        >
                    >
                >
                retourner -1 ;
            >
        }();

var Rappels = fonction (option) {
          option = toString.call(option) === '[objet Objet]' option : {};
​​​​ //Utilisez les fermetures car chaque nouveau rappel a son propre état
        var list = [],                                                                                                         var list =                               _list = [],        // Si cet objet de rappel est verrouillé, effacez la liste et placez la liste d'origine dans _list
                                                                                                                                                                                     ont été exécutés
shootingStart, //Index de fonction (point de départ) exécuté par la liste de fonctions de rappel actuelle
              ignitionLength,                                                                        // Longueur du tableau de la fonction de rappel
                                                                                                                                                                                                                                              .                              // L'utilisation de cette variable est très étrange et pointue, elle contient non seulement l'indicateur indiquant s'il faut spécifier l'exécution, mais enregistre également les données
//Cette auto est tout simplement folle lorsqu'elle est utilisée avec une fois : [Pour la première fois] elle sera automatiquement exécutée après l'exécution de Fire Avec une fois, cela peut être fait : une fois exécuté, aucun code ne sera ajouté ou exécuté plus tard, assurant la stabilité. et la stabilité d'un ensemble de données de rappel. Safe
. stack = !option.once && [], //Une pile de rappels est en cours d'exécution et qu'une nouvelle fonction de rappel est ajoutée pendant l'exécution, alors la nouvelle fonction de rappel sera poussée dans le tableau de rappel<🎜. >             shooting = false, //Si les rappels fonctionnent/s'exécutent
//Fonction de rappel de déclenchement
feu = fonction (données) {
// Notez que ces données sont un tableau. Si le mode auto est configuré, auto ne sera jamais faux car auto sera un tableau
.                     auto = option.auto && data //Ici, si la configuration nécessite de mémoriser le dernier paramètre, alors mémorisez ce paramètre (utilisation très pointue, récupérer directement les données)
viré = vrai ;
shootingIndex = shootingStart || 0;
                FireStart = 0;//Effacer FireStart (si vous ne l'effacez pas, il y aura des problèmes lors de la prochaine exécution)
Firinglength = list.length; // longueur de la liste de cache, le monde extérieur peut accéder à
                  shooting = true ; // Exécution de la fonction de rappel
pour (; FireIndex < FireLength; FireIndex ) {
Si (list[firingIndex].apply(data[0], data[1]) === false) {
// Notez que si option.auto (exécution automatique) est configuré et qu'il y a une fonction dans la pile (stack), alors il y a une section de code dans le code add() qui exécutera directement cette méthode pour le jugement automatique
//Nous voulons bloquer ce code, alors définissez auto sur false
                                  auto = false;
                          pause ;
                                    }//Lorsque la fonction renvoie false, terminez l'exécution de la file d'attente suivante
                }
                shooting = false ; // L'état du drapeau a été exécuté, fonction de rappel [la fonction dans la pile (stack) n'a pas encore été exécutée]
//Si cette pile n'est pas configurée une seule fois, elle doit être [], donc il doit y avoir
//La fonction principale ici est que si une fois n'est pas configuré, le code suivant sera intercepté. Si une fois est configuré, les données seront effacées après l'exécution du code
.                      if (pile) {
If (stack.length) // Interceptez d'abord le code de l'état de liste ci-dessous, puis déterminez s'il existe une pile
Fire (stack.shift ()); // Sortez-le de la tête de la pile et répétez la méthode FIRE ()
                }
Sinon, si (auto) // le code est venu ici, prouve qu'il a été configuré Option.once (une seule fois exécuté), donc la liste est claire
                   list = [];
Sinon // prouve qu'il n'y a pas de configuration AUTO, mais ONCE est configuré, donc le sacrifice est le Dafa ultime, et l'objet de rappel est directement aboli
                        self.disable();
            };
      var soi = {
               add : function () {//Ajouter une fonction de rappel
                        if (liste) {
                  var start = list.length;
(fonction addCallback(args) {
chacun (arguments, fonction (élément) {
If (isFunction(item)) {//S'il s'agit d'une fonction, poussez la liste de rappel
                                                                                                                                    //Notez que typeof et Object.prototype.toString sont différents
                              } else if (toString.call(item) === '[object Array]') {//S'il s'agit d'un tableau, poussez de manière récursive dans la liste de rappel, ce jugement abandonne le type de tableau
                                                                                                                                                            addCallback(item);
                                                                                                   }                               });
                         })(arguments);
                }
Si (tiring)//Si une fonction de rappel est en cours d'exécution, alors la longueur de la liste actuelle des fonctions de rappel doit être mise à jour, sinon la fonction de rappel nouvellement poussée sera ignorée.
shootingLength = list.length;
                  else if (auto) {//Si la fonction de rappel n'est pas actuellement exécutée et qu'une exécution automatique est requise
                                                                                                                                                                                                                           // Notez que la valeur est attribuée à FireStart. Cela n'affectera pas la ligne d'exécution du code ci-dessus
shootingStart = démarrer;
//Exécuter nos partenaires nouvellement ajoutés
feu(auto);
                }
                   renvoyez ceci ;
            },
               fire: function () {//Déclencher la fonction de rappel
                     self.fireWith(this, arguments);
                   renvoyez ceci ;
            },
​​​​​​ fireWith: function (context, args) {//Déclenchez la fonction de rappel et spécifiez le contexte
//Si once est configuré, la pile ne sera pas définie et once doit être garanti pour être exécuté une seule fois, donc une fois exécuté une fois, le code ici ne sera plus exécuté
If (list && (!fired || stack)) {
//Paramètres de correction
//Ici, l'index de contexte est 0
//L'index de la liste des paramètres est 2
// La conversion en accès au tableau est due au fait que la représentation d'objet consomme plus de ressources. Il existe une fonction auto [paramètres de mémoire, exécution automatique] dans le code fire() de niveau supérieur. Si des objets sont utilisés, plus de mémoire sera consommée
.                      args = [contexte,
                                                                                                                                 args.slice && args.slice()
                                                                                                                                                                         ];
feu(arguments);
                }
                   renvoyez ceci ;
            },
               delete: function () {//Supprimer une fonction de rappel
                        if (liste) {
chacun (arguments, fonction (élément) {
                     var index ;
                                        // Il peut y avoir plusieurs éléments, l'index peut représenter la plage de recherche dans la boucle et les éléments précédemment recherchés n'ont pas besoin d'être recherchés à nouveau
Tandis que ((index = inArray(item, list, index)) > -1) {
                                           list.splice(index, 1);
Si (tir) {
//Assurez-vous que la liste de fonctions exécutée dans Fire ci-dessus peut s'exécuter correctement. Ces variables globales sont définies dans Fire afin qu'elles puissent être supprimées de manière asynchrone
. Si (index <= longueur de tir)//longueur de correction
longueur de tir--;
Si (index <=fireLength)//Indice de correction
shootingIndex--;
                                                                                                   }                                                                                                           }                      });
                }
                   renvoyez ceci ;
            },
A : function (fn) {//Qu'il contienne une fonction de rappel
? (fn, liste) > -1 : liste && list.length;
            },
              vide : function () {//Vider cet objet de rappel
liste = [];
longueur de tir = 0;
                   renvoyez ceci ;
            },
                désactiver : function () {//Détruisez cet objet de rappel et la liste de fonctions de rappel suivante ne sera plus exécutée
                   list = stack = auto = undefined;
                   renvoyez ceci ;
            },
              désactivé : fonction () {//Si elle a été désactivée
& nbsp

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal