Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung von Rückrufen im jQuery-Quellcode „analysis_jquery“.

Detaillierte Erläuterung von Rückrufen im jQuery-Quellcode „analysis_jquery“.

WBOY
WBOYOriginal
2016-05-16 16:09:471297Durchsuche

Das Wesen des Codes unterstreicht das Konzept von Sequenz und Reihenfolge, insbesondere in JavaScript – schließlich ist JavaScript eine Single-Threaded-Engine.

Javascript hat die Eigenschaften einer funktionalen Programmierung und aufgrund der JavaScript-Single-Threaded-Engine müssen unsere Funktionen immer in geordneter Weise ausgeführt werden. Hervorragender Code schneidet Funktionen häufig in ihre eigenen Module ein und führt sie dann unter bestimmten Bedingungen aus. Da diese Funktionen auf geordnete Weise ausgeführt werden, schreiben wir doch ein einheitliches Verwaltungsobjekt, das uns bei der Verwaltung dieser Funktionen hilft – also Callbacks (Rückruffunktionen). ) wurden geboren.

Was sind Rückrufe?

Javascript ist voll von funktionaler Programmierung. Das Traurigste ist, dass window.onload nur eine Funktion empfangen kann, wenn es mehrere Funktionen gibt, die Sie möchten in Onload ausführen, dann müssen wir den folgenden Code schreiben:

Code kopieren Der Code lautet wie folgt:

Funktion a(elem) {
                elem.innerHTML = 'Ich bin Funktion a, ich möchte die HTML-Struktur von Element ändern';
        };
         Funktion b(elem) {
                elem.innerHTML = 'Meine Funktion b, ich möchte den Stil von Element ändern';
}
          window.onload = function () {
               var elem = document.getElementById('test');
a(elem);
              b(elem);
        };

Die ursprüngliche Absicht der Rückruffunktion besteht darin, auf so etwas aufzubauen. Sie ermöglicht uns nicht mehr, diese Funktionen zu verstreuen, sondern diese Funktionen auf einheitliche Weise zu organisieren. Wie Sie sehen, möchten wir für ein Element in window.onload zwei Dinge tun: Zuerst die HTML-Struktur ändern und dann den Stil des HTML ändern. Die beiden Funktionen wirken auch auf ein Element, und die endgültige Ausführung dieser beiden Funktionen erfolgt der Reihe nach. Warum schreiben wir also nicht ein Objekt wie dieses, um diese Funktionen zu verwalten? Dies ist natürlich nur die grundlegendste Bedeutung der Callback-Funktion. Wir brauchen mehr als nur ein solches einfaches Callback-Funktionsobjekt, wir brauchen eine leistungsfähigere Callback-Funktion. Nun, das ist nur ein einfacher Anwendungsfall, also kann ich Ihnen sagen, was diese Rückruffunktion tun kann, außer Funktionen einzeln auszuführen.

Der Kern von Callbacks besteht darin, die ordnungsgemäße Ausführung von Funktionen zu steuern. Javascript ist eine Single-Threaded-Engine, was bedeutet, dass nur ein Code in JavaScript gleichzeitig ausgeführt wird – sogar Ajax und setTimeout. Diese beiden Funktionen scheinen asynchron zu sein, aber das ist nicht der Fall. Wenn der Browser Javascript-Code ausführt, werden diese Codes in geordneter Weise in eine Warteschlange verschoben Der Browser entnimmt den Code nacheinander aus der Codewarteschlange, wenn er den JavaScript-Code verarbeitet – Rückrufe, die dieser Single-Thread-Engine gerecht werden.

Natürlich wollen wir mehr als nur ein so einfaches Toolobjekt – im jQuery-Quellcode stellen Callbacks die grundlegende Verwaltung einer Reihe von Funktionen bereit, bilden die Grundlage für Deferred (asynchrone Warteschlange) und dienen auch der Warteschlange (Synchronisierungswarteschlange). Deferred wird verwendet, um die Pyramidenprogrammierung zu glätten/abzuflachen (eine große Anzahl verschachtelter Rückruffunktionen, z. B. Code in Ajax, der basierend auf dem Anforderungsrückgabecode ausgeführt werden muss); und Queue steuert jQuery.animate (Animations-Engine).

Dann schreiben wir einen Rückruf.

Rückrufmodell

Array:
Da unsere Callbacks eine Reihe von Funktionen akzeptieren möchten, müssen wir einen Container haben. Wir können ein Array verwenden und jede Funktion in das Array verschieben. Wenn sie ausgeführt werden muss, führen Sie eine Schleife durch die auszuführenden Array-Elemente durch.

Arbeitsmodell:

Diese Rückrufe müssen sehr leistungsfähig sein. Es ist nicht nur so einfach, eine Funktion zu pushen und dann auszuführen. Diese Rückrufe sollten ein gutes Ausführungsmodell haben.
einmal: Alle Funktionen im aktuellen Callbacks-Objekt werden nur einmal ausgeführt und nach der Ausführung freigegeben. Wir können Benutzern, die das Callbacks-Objekt verwenden, eine stabile und effektive Lösung bieten, um sicherzustellen, dass die Funktion nur einmal ausgeführt wird erneut ausgeführt werden, was die Threads dieser Funktionen stabilisiert.
auto: Dies ist ein interessantes Modell. Beispielsweise hängt die Ausführung der Funktion b von der Funktion a ab: Nach der ersten Ausführung dieses Rückrufs. Jedes Mal, wenn die Funktion die Rückrufe erreicht, führt sie automatisch die in der Vergangenheit hinzugefügten Funktionen aus und übergibt die letzten Parameterdaten an die früheren Funktionen. Dadurch entfällt die Notwendigkeit einer wiederholten Auslösung zwischen diesen abhängigen Funktionen ein interessantes Modell.
Once&Auto: Wir können es leistungsfähiger machen und gleichzeitig mit den Once- und Auto-Modellen arbeiten, das heißt: Jedes Mal, wenn eine Funktion zu Callbacks hinzugefügt wird, werden die früheren Funktionen ausgeführt und dann werden diese früheren Funktionen freigegeben. und Funktionen werden beim nächsten Mal weiterhin hinzugefügt. Zu diesem Zeitpunkt werden diese Funktionen in der Vergangenheit nicht mehr ausgeführt, da das einmalige Modell sie freigegeben hat.

API:

add(function) – Fügen Sie eine (oder mehrere) Funktionen zum Callbacks-Objekt hinzu: Wenn Sie keine Funktionen hinzufügen und einfach nur neugierig sind, einen Blick auf Callbacks zu werfen, lassen wir Sie natürlich weiterhin Ihren Spaß genießen - Wir werden keine Ausnahme auslösen, weil wir darin nicht gut sind.
remove(function) – entfernt eine Funktion in einem Callbacks: Nachdem wir sie hinzugefügt haben, sollten wir auch einen Plan bereitstellen, um sie zu bereuen. Wir sind so zugänglich und tolerieren alles, was andere in der Vergangenheit getan haben.
has(function) – Bestimmt, ob Callbacks eine Funktion enthalten: Oh? Sie sind sich nicht sicher, ob Sie diese Funktion einbinden sollen, aber Sie haben sie von Anfang an eingebaut! Warum bist du so nachlässig? Aber da Sie mich gefragt haben, werde ich Ihnen trotzdem sagen, ob Callbacks diese Funktion enthält. Ich weiß, dass Sie sehr beschäftigt sind und sich nicht an alles erinnern und es bestimmen können.
empty() – Leere Rückrufe: Haben diese Funktionen für Sie ihre Bedeutung verloren? Was? Sie möchten es nach der Ausführung nicht mehr? Du wünschst dir also, du könntest es klären? Nun, der Erinnerung halber toleriere ich Ihre Forderung immer noch.
disable() – Callbacks deaktivieren: Um eine stabile Existenz mit dem Code anderer Leute aufrechtzuerhalten, habe ich mich für Selbstaufopferung entschieden – ja, diese Methode kann Callbacks deaktivieren, sie vollständig deaktivieren, als ob sie vorher nicht existiert hätte.
disabled() – Stellt fest, ob die Callbacks deaktiviert wurden: Wenn Sie immer noch nicht glauben, ob die Callbacks wirklich aufopferungsvoll sind, kann Ihnen diese Methode Sicherheit geben.
lock(boolean) – Sperren Sie dieses Callbacks-Objekt: Sie befürchten, dass es instabil ist, aber Sie möchten es nicht aufgeben. Es ist eine gute Methode, um anzugeben, ob das Objekt gesperrt werden muss Natürlich gibt es keine Parameter. Damit können Sie bestimmen, ob Rückrufe gesperrt sind.
fire(data) – Führen Sie die Funktion in diesen Rückrufen aus: Ist nicht alles, was wir tun, in diesem Moment für das Schicksal der Ausführung bestimmt? Die Parameter werden zu Parametern dieser Funktionen, die ausgeführt werden müssen.
fireWith(context,data) – Führen Sie die Funktion in Callbacks aus und geben Sie den Kontext an. In fire() ist der Kontext aller Funktionen Callbacks-Objekte, und fireWidth() ermöglicht es Ihnen, den Kontext dieser auszuführenden Funktionen neu zu definieren. Wie frei die Programmierung ist, berücksichtigt Callbacks alles für Sie.
fired() – Stellen Sie fest, ob dieser Callbacks in der Vergangenheit ausgeführt wurde: Wir glauben, dass Sie die meiste Zeit nicht wissen, was Sie in der Vergangenheit getan haben, aber wir zeichnen alles auf, was Sie tun, wenn Sie dieses Callbacks-Objekt ausgeführt haben die Vergangenheit, dann können Sie es nie leugnen, denn wir wissen, ob Sie diese Rückrufe in der Vergangenheit ausgeführt haben.

Grundlegende Modulimplementierung

Einfache Implementierung:
Lassen Sie uns zunächst einfach einen Rückruf implementieren:

Code kopieren Der Code lautet wie folgt:

(Funktion (Fenster, undefiniert) {
            var Callbacks = function () {
//Diese privaten Variablen durch Schließungen schützen
                   var list = [],//Rückruffunktionsliste
Gefeuert; // Haben Sie ausgeführt
//Ein Abschluss-Callbakcs-Objekt zurückgeben
                   zurück {
                         hinzufügen: Funktion (fn) {
//Wenn Rückrufe verworfen werden, ist die Liste undefiniert
Wenn (Liste) {
//Rückruffunktion hinzufügen
                                 list.push(fn);
//Rückrufe der Support-Kette
                                                                                                       }                                                                                        zurückgeben;                     },
fireWith: Funktion (Kontext, Daten) {
//Lösen Sie die Rückruffunktion aus und geben Sie den Kontext an
Wenn (Liste) {
gefeuert = wahr;
for (var i = 0, len = list.length; i < len; i ) {
//Wenn eine Funktion in Callbacks „false“ zurückgibt, stoppen Sie die nachfolgende Ausführung von Callbacks
If (list[i].apply(context, data) === false)
Pause;
                                                                                               }                                                                                                        }                                                                                        zurückgeben;                     },
Feuer: Funktion () {
//Rückruffunktion auslösen
//Rufen Sie fireWith auf und geben Sie den Kontext an
Gibt this.fireWith(this, arguments);
zurück                     },
                      leer: Funktion () {
//Löschen Sie die Liste
                                                                                                                                            if (Liste)//Wenn diese Rückrufe verworfen werden, sollten Rückrufe nicht weiter verwendet werden können
list = [];
                                                                                       zurückgeben;                     },
                           deaktivieren: Funktion () {
//Dieses Callbacks-Objekt aufgeben und die nachfolgende Callback-Funktionsliste wird nicht mehr ausgeführt
                         list = undefiniert;
                                                                                       zurückgeben;                     },
                       deaktiviert: Funktion () {//Erkennen Sie, ob diese Rückrufe deaktiviert wurden
//In booleschen Wert konvertieren und
zurückgeben Geben Sie !list;
zurück                     },
                     fired: function () {//Ob diese Rückrufe ausgeführt wurden
                                                                                                                                                                                                            }
                };
            };
//Im Fenster registrieren
               window.Callbacks = Callbacks;
         }(Fenster));



Dann testen wir diese Rückrufe:

Code kopieren Der Code lautet wie folgt:

        var test = new Callbacks();
         test.add(function (value) {
                console.log('Funktion 1, Wert ist: ' Wert);
        });
         test.add(function (value) {
​​​​​​ console.log('Funktion 2, Wert ist:' Wert);
        });
​​​​ test.fire('Dies ist der Wert von Funktion 1 und Funktion 2');
console.log('Überprüfen Sie, ob die Funktion ausgeführt wurde:' test.fired());
         test.disable();//Diese Rückrufe aufgeben
console.log('Überprüfen Sie, ob die Funktion abgebrochen wurde:' test.disabled());
         test.add(function () {
console.log('Eine dritte Funktion hinzufügen, diese Funktion sollte nicht ausgeführt werden');
        });
         test.fire();

Öffnen Sie die Browserkonsole und wir können sehen, dass die Laufergebnisse normal sind.

einmalige und automatische (Speicher-)Implementierung

einmal:
Once lässt die Funktion in diesem Rückruf einmal ausführen und dann nicht erneut ausführen. Das Prinzip ist sehr einfach. Im obigen Code können wir sehen, dass es eine Variablenliste gibt, die die Funktionsliste übernimmt, sodass wir nur die Codes löschen müssen, die in der Vergangenheit ausgeführt wurden. Wir verwenden eine globale Variable, um das aktuelle Ausführungsmodell zu speichern. Wenn es sich um ein einmaliges Modell handelt, machen Sie die Liste einfach in fireWith() ungültig:

Code kopieren Der Code lautet wie folgt:

(Funktion (Fenster, undefiniert) {
            var Callbacks = function (once) {
//Diese privaten Variablen durch Schließungen schützen
                   var list = [],//Rückruffunktionsliste
Gefeuert; // Haben Sie ausgeführt
//Ein Abschluss-Callbakcs-Objekt zurückgeben
                   zurück {
//...Einigen Code weglassen
fireWith: Funktion (Kontext, Daten) {
//Lösen Sie die Rückruffunktion aus und geben Sie den Kontext an
Wenn (Liste) {
gefeuert = wahr;
for (var i = 0, len = list.length; i < len; i ) {
//Wenn eine Funktion in Callbacks „false“ zurückgibt, stoppen Sie die nachfolgende Ausführung von Callbacks
If (list[i].apply(context, data) === false)
Pause;
                                                                                               }                                                                                                        } //Wenn das Once-Modell konfiguriert ist, ist die globale Variable Once wahr und die Liste wird zurückgesetzt
Wenn (einmal) Liste = undefiniert;
                                                                                       zurückgeben;                  }
//...Einigen Code weglassen
                };
            };
//Im Fenster registrieren
               window.Callbacks = Callbacks;
         }(Fenster));

automatisch:

Das Auto-(Speicher-)Modell ist nach dem Speicher in jQuery benannt. Nachdem ich mir die Verwendung genau angesehen hatte, entschied ich mich, es in „Auto“ zu ändern – seine Funktion ist „nach dem ersten Feuer()“. Die nachfolgende Funktion „add() wird automatisch ausgeführt“ kann in den folgenden Situationen verwendet werden: Nachdem Sie eine Reihe von Funktionen zu Callbacks hinzugefügt haben und vorübergehend eine Funktion hinzufügen müssen, führen Sie die neu hinzugefügte Funktion sofort aus Benutzerfreundlichkeit. Dieses Muster ist etwas schwer zu verstehen. Die Implementierung besteht darin, während add() festzustellen, ob es sich um ein automatisches Modell handelt. Wenn es sich um ein automatisches Modell handelt, führen Sie diese Funktion aus. Allerdings müssen wir es nach dem ersten fire() automatisch ausführen. Rückrufe, die nicht fire() wurden, sollten nicht automatisch ausgeführt werden. Außerdem müssen nach jeder automatischen Ausführung die zuletzt verwendeten Parameter an diese automatisch ausgeführten Funktionen übergeben werden.

Vielleicht fällt Ihnen der folgende Code ein:

Code kopieren Der Code lautet wie folgt:

(Funktion (Fenster, undefiniert) {
            var Callbacks = Funktion (einmal, automatisch) {
              var list = [],
gefeuert,
lastData;//Speichern Sie die Parameter der letzten Ausführung
                   zurück {
                         hinzufügen: Funktion (fn) {
Wenn (Liste) {
                                 list.push(fn);
​​​​​​​​​​​​​ //Der zuletzt verwendete Parameter wird übergeben und der Kontext geht hier verloren
//Um zu verhindern, dass der Kontext hier verloren geht, müssen wir möglicherweise auch eine Variable deklarieren, um den zuletzt verwendeten Kontext zu speichern
If (auto) this.fire(lastData);
                                                                                                       }                                                                                        zurückgeben;                     },
fireWith: Funktion (Kontext, Daten) {
Wenn (Liste) {
lastData = data;// – Den zuletzt verwendeten Parameter aufzeichnen
gefeuert = wahr;
for (var i = 0, len = list.length; i < len; i ) {
If (list[i].apply(context, data) === false)
Pause;
                                                                                               }                                                                                                        } If (once) list = [];
                                                                                       zurückgeben;                  }
//Ein Teil des Codes wird weggelassen
                };
            };
//Im Fenster registrieren
               window.Callbacks = Callbacks;
         }(Fenster));

Aber in jQuery wird auch eine wunderbarere Verwendung übernommen. Der Autor von jQuery ist auch stolz auf diese Verwendung, daher hat er dieses Modell „Speicher“ genannt – das heißt, die obige Variable stellt nicht nur den aktuellen automatischen Ausführungsmodus dar, sondern dient auch als letzter Parametercontainer, der sowohl Auto als auch Speicher darstellt. (Der folgende Code ist kein jQuery und basiert auf Ideen für jQuery-Code, nicht auf Quellcode):

Code kopieren Der Code lautet wie folgt:

(Funktion (Fenster, undefiniert) {
            var Callbacks = function (auto) {
              var list = [],
gefeuert,
Erinnerung,//Der Hauptdarsteller ist hier, es ist die Erinnerung
coreFire = Funktion (Daten) {
//Die eigentliche Triggerfunktionsmethode
Wenn (Liste) {
                                                                                                                            Speicher = Auto && Daten; // Den letzten Parameter aufzeichnen. Wenn es sich nicht im Auto-Modus befindet, wird dieser Parameter nicht aufgezeichnet
//Wenn es sich um den automatischen Modus handelt, ist dieses Auto nicht falsch, sondern ein Array
gefeuert = wahr;
for (var i = 0, len = list.length; i < len; i ) {
If (list[i].apply(data[0], data[1]) === false)
Pause;
                                                                                               }                                                                                                        }                     };
                   zurück {
                         hinzufügen: Funktion (fn) {
Wenn (Liste) {
//Rückruffunktion hinzufügen
                                 list.push(fn);
//Automatischer Ausführungsmodus, beachten Sie, dass das automatische Modell
//Speicher wird in coreFire() zugewiesen, der Standardwert ist false
Wenn (Speicher) coreFire(auto);
                                                                                                       } //Rückrufe der Support-Kette
                                                                                       zurückgeben;                    },
fireWith: Funktion (Kontext, Daten) {
If (once) list = [];
// Hier coreFire aufrufen und die Parameter in ein Array konvertieren
coreFire([context, data]);
                                                                                       zurückgeben;                  }
                                                                                                                                                                                                                                                       };
            };
               window.Callbacks = Callbacks;
         }(Fenster));


Wir haben im Code der vorherigen automatischen Implementierung gesehen, dass wir den Kontext verloren haben. jQuery hat diesen Fehler frühzeitig in fireWith() behoben – die Parameter in fireWith() behoben. jQuery extrahiert die Logik, die die Funktion in fireWith() ausführen soll. Wir nennen sie vorübergehend coreFire(). Im ursprünglichen fireWith() werden die Parameter in ein Array gespleißt: Der erste Parameter repräsentiert den Kontext und der zweite Parameter Parameter stellen die übergebenen Parameter dar. Führen Sie dann coreFire() aus.


Während add() hat jQuery der Variablen auto(memory) keinen Wert zugewiesen, sondern sich dafür entschieden, auto(memory) in coreFire() einen Wert zuzuweisen, um sicherzustellen, dass es erst beim ersten Mal aktiviert wird fire(). Automatisch ausgeführt.


Wie oben erwähnt, sind die von coreFire() empfangenen Parameter tatsächlich ein Array. Der erste Parameter ist der Kontext und der zweite Parameter ist der von außen übergebene Parameter. Weisen Sie dieses Array gleichzeitig auto (Speicher) zu, sodass die Definition der Variablen auto (ob der Modus automatisch ausgeführt werden soll) zum Speicher (Speicher des zuletzt übergebenen Parameters) wird.

Es ist wirklich eine geniale Idee, die zwei Fliegen mit einer Klappe schlägt. Sie muss mir gefallen. Ich definiere dies als automatisch, da es sich um ein automatisch ausgeführtes Modell handelt und die Parameter des letzten Feuers () gespeichert werden. Die Definition von jQuery als Speicher ist möglicherweise der Seufzer des Autors für die wundersame Verarbeitung hier.


Was Once&Auto betrifft, werden nur diese beiden Codes kombiniert. Sie müssen in coreFire() nur festlegen, dass die Liste im automatischen Modus auf ein neues Array zurückgesetzt wird, andernfalls wird sie direkt auf undefiniert gesetzt.

Quellcode

Dieser Code wurde von mir handgeschrieben und entspricht einigen öffentlichen jQuery-Funktionen. Es handelt sich nicht um ein Codefragment, daher kann direkt darauf verwiesen und ausgeführt werden.

Code kopieren Der Code lautet wie folgt:

(Funktion (Fenster, undefiniert) {
/*
* Ein Callback-Funktions-Toolobjekt. Beachten Sie, dass das Array gelöscht wird, nachdem das Arbeitsobjekt abgeschlossen ist:
* * Bietet einen gemeinsamen Satz von APIs, verfügt jedoch über das folgende Arbeitsmodell:
​​​ *Auto - Automatisches Ausführungsmodell: Bei jedem Hinzufügen einer Rückruffunktion werden automatisch alle Rückruffunktionen im vorhandenen Rückruffunktionssatz ausgeführt, und die Parameter dieser Zeit werden an alle Rückruffunktionen übergeben
*
*/

//Werkzeugfunktion
var isIndexOf = Array.prototype.indexOf, //Es6
        toString = Object.prototype.toString, //Cache toString-Methode
TosLice = Array.prototype.slice, // Caches Slice-Methode
                                                                                                                                                                                                return "object" === typeof document.getElementById ?
               isFunction = function (fn) {
                      //Es gibt ein Problem mit der Erkennung von DOM und BOM unter ie
                  versuchen Sie es mit {
Geben Sie /^s*bfunctionb/.test("" fn);
zurück                         } Catch (x) {
Gibt false zurück
                }
              } :
               isFunction = function (fn) { return toString.call(fn) === '[object Function]' };
         })(),
                                                                                                                                                                                              //Der erste Parameter stellt das Array dar, das in einer Schleife ausgeführt werden soll, und der zweite Parameter ist die Funktion, die jedes Mal durch die Schleife
ausgeführt wird If (arguments.length < 2 || !isFunction(arguments[1])) return;
                       //Warum ist Slice ungültig? ?
          var list = toSlice.call(arguments[0]),
                             fn = arguments[1],
Artikel;
​​​​​​while ((item = list.shift())) {//Keine direkte Bestimmung der Länge, beschleunigen
// Warum hier „Call“ verwenden und „Apply“ nicht in Ordnung ist?
                               // Fertig – der zweite Parameter von apply muss ein Array-Objekt sein (es gibt keine Überprüfung, ob Array-like möglich ist, und für den Aufruf gilt diese Anforderung nicht)
                                                                                                                                    //apply wird wie folgt beschrieben: Wenn argArray (der zweite Parameter) kein gültiges Array oder kein Argumentobjekt ist, wird ein TypeError verursacht.
                           fn.call(window, item);
            }
},
inArray = function () { //Erkennen Sie, ob das Array ein Element enthält, und geben Sie den Index des Elements zurück
                                                                                                                                                    // Vorkompilierung
                 return isIndexOf ? function (array, elem, i) {
Wenn (Array)
                          return isIndexOf.call(array, elem, i);
                    return -1;
               } : Funktion (elem, array, i) {
              var len;
                     if (array) {
                    len = array.length;
                    ich = ich ? ich < 0 ? Math.max(0, len i) : i : 0;
                    für (; i < len; i ) {
                        if (i in array && array[i] === elem) {
                            zurück i;
                        }
                    }
                }
                return -1;
            }
        }();

var Callbacks = Funktion (Option) {
          option = toString.call(option) === '[object Object]' ? option: {};
​​​​ //Abschlüsse verwenden, da jeder neue Rückruf seinen eigenen Status hat
        var list = [],                                                       var list = [],                                                                                          var list =                               _list = [],        // Wenn dieses Rückrufobjekt gesperrt ist, löschen Sie die Liste und fügen Sie die ursprüngliche Liste in _list
ein                                                                                                                                                                              wurden hingerichtet
fireStart, //Funktionsindex (Startpunkt), der von der aktuellen Callback-Funktionsliste
ausgeführt wird               FiringLength,                                                                     // Array-Länge der Callback-Funktion
                                                                                                                                                                                                                                     .                              // Die Verwendung dieser Variablen ist sehr seltsam und scharfsinnig. Sie enthält nicht nur das Flag, ob die Ausführung angegeben werden soll, sondern zeichnet auch die Daten auf
//Dieses Auto ist einfach verrückt, wenn es mit Once verwendet wird: [Zum ersten Mal] wird es nach der Ausführung von Fire automatisch ausgeführt. Mit Once ist dies möglich: Nach der Ausführung wird kein Code angehängt oder später ausgeführt, um die Stabilität zu gewährleisten und Stabilität eines Satzes von Rückrufdaten stack = !option.once && [], //Ein Callback-Array wird gerade ausgeführt und während der Ausführung wird eine neue Callback-Funktion hinzugefügt >             Firing = false, //Ob Rückrufe funktionieren/ausgeführt werden
//Rückruffunktion auslösen
Feuer = Funktion (Daten) {
//Beachten Sie, dass es sich bei diesen Daten um ein Array handelt. Wenn der Auto-Modus konfiguriert ist, ist auto niemals falsch, da auto ein Array ist
                    auto = option.auto && data //Wenn die Konfiguration das Speichern des letzten Parameters erfordert, dann merken Sie sich diesen Parameter (sehr scharfe Verwendung, rufen Sie die Daten direkt ab)
gefeuert = wahr;
FiringIndex = FiringStart ||. 0;
                FiringStart = 0;//FiringStart löschen (wenn Sie es nicht löschen, wird es bei der nächsten Ausführung Probleme geben)
Firinglength = list.length; // Länge der Cache-Liste, auf die die Außenwelt zugreifen kann
                  Firing = true; // Rückruffunktion wird ausgeführt
für (; FiringIndex < FiringLength; FiringIndex) {
If (list[firingIndex].apply(data[0], data[1]) === false) {
// Hinweis: Wenn option.auto (automatische Ausführung) konfiguriert ist und sich eine Funktion im Stapel (Stapel) befindet, gibt es im add()-Code einen Codeabschnitt, der diese Methode zur automatischen Beurteilung direkt ausführt
//Wir wollen diesen Code blockieren, also setze auto auf false
                                  auto = false;
                          Pause;
                                    }//Wenn die Funktion false zurückgibt, beenden Sie die Ausführung der nachfolgenden Warteschlange
                }
                Firing = false; // Flag-Status wurde ausgeführt. Callback-Funktion [die Funktion im Stapel (Stack) wurde noch nicht ausgeführt]
//Wenn dieser Stapel nicht einmal konfiguriert wird, muss er [] sein, also muss es
geben // Die Hauptfunktion besteht darin, dass der folgende Code abgefangen wird, wenn Once nicht konfiguriert ist. Wenn Once konfiguriert ist, werden die Daten nach der Ausführung des Codes gelöscht                      if (stack) {
If (stack.length) // Fangen Sie zuerst den Code des folgenden Auflistungsstatus ab und bestimmen Sie dann, ob ein Stapel
vorhanden ist Fire (stack.shift()); // Nimm es aus dem Kopf des Stapels und rekurriere die FIRE()-Methode
                }
Sonst, wenn (auto) // Code hierher kam, beweist dies, dass er Option.once konfiguriert wurde (nur einmal ausgeführt), sodass die Liste klar ist
                   list = [];
Else // beweist, dass es keine AUTO-Konfiguration gibt, sondern ONCE konfiguriert ist, sodass das Opfer das ultimative Dafa ist und das Rückrufobjekt direkt abgeschafft wird
                        self.disable();
            };
      var self = {
               add: function () {//Eine Rückruffunktion hinzufügen
                        if (Liste) {
                  var start = list.length;
(Funktion addCallback(args) {
every(args, function (item) {
If (isFunction(item)) {//Wenn es sich um eine Funktion handelt, drücken Sie die Rückrufliste
                                                                                                                               //Beachten Sie, dass typeof und Object.prototype.toString unterschiedlich sind
                              } else if (toString.call(item) === '[object Array]') {//Wenn es sich um ein Array handelt, wird es rekursiv in die Rückrufliste verschoben. Dieses Urteil wird arrayartig aufgegeben
                                                                                                                                                     addCallback(item);
                                                                                               }                               });
                         })(Argumente);
                }
Wenn (auslösend)//Wenn gerade eine Rückruffunktion ausgeführt wird, muss die Länge der aktuellen Rückruffunktionsliste aktualisiert werden, andernfalls wird die neu gepushte Rückruffunktion übergeben.
FiringLength = list.length;
                  else if (auto) {//Wenn die Rückruffunktion derzeit nicht ausgeführt wird und eine automatische Ausführung erforderlich ist
                                                                                                                                                                                  hat keinen Einfluss auf die Ausführungszeile des obigen Codes
FiringStart = Start;
//Führen Sie unsere neu hinzugefügten Partner aus
Feuer(automatisch);
                }
                   gib dies zurück;
            },
               fire: function () {//Rückruffunktion auslösen
                     self.fireWith(this, arguments);
                   gib dies zurück;
            },
​​​​​​ fireWith: function (context, args) {//Lösen Sie die Rückruffunktion aus und geben Sie den Kontext an
//Wenn einmal konfiguriert ist, ist der Stapel undefiniert und es muss garantiert werden, dass er nur einmal ausgeführt wird. Wenn er also einmal ausgeführt wird, wird der Code hier nicht erneut ausgeführt
If (list && (!fired || stack)) {
//Korrekturparameter
//Hier ist der Kontextindex 0
//Der Parameterlistenindex ist 2
// Die Konvertierung in den Array-Zugriff liegt daran, dass die Objektdarstellung mehr Ressourcen verbraucht. Es gibt eine automatische Funktion [Speicherparameter, automatische Ausführung] im Fire()-Code der obersten Ebene. Wenn Objekte verwendet werden, wird mehr Speicher verbraucht
                     args = [context,
                                                                                                                                    args.slice && args.slice()
                                                                                                                                                                 ];
fire(args);
                }
                   gib dies zurück;
            },
               remove: function () {//Eine Rückruffunktion entfernen
                        if (Liste) {
every(arguments, function (item) {
                      var index;
                                        // Es können mehrere Elemente vorhanden sein, der Index kann den Suchbereich in der Schleife darstellen und die zuvor gesuchten Elemente müssen nicht erneut durchsucht werden
While ((index = inArray(item, list, index)) > -1) {
                                          list.splice(index, 1);
Wenn (feuernd) {
//Stellen Sie sicher, dass die oben in Fire ausgeführte Funktionsliste korrekt ausgeführt werden kann. Diese globalen Variablen werden in Fire gesetzt, damit sie asynchron entfernt werden können
If (index <= FiringLength)//Korrekturlänge
FiringLength--;
If (index <= FiringLength)//Korrekturindex
FiringIndex--;
                                                                                               }                                                                                                        }                      });
                }
                   gib dies zurück;
            },
Hat: Funktion (fn) {//Ob es eine Rückruffunktion enthält
                                                                                                        return fn ? inAr ray(fn, list) > -1 : list && list.length;
            },
              empty: function () {//Dieses Rückrufobjekt leeren
list = [];
FiringLength = 0;
                   gib dies zurück;
            },
                deaktivieren: Funktion () {// Zerstören Sie dieses Rückrufobjekt, und die nachfolgende Rückruffunktionsliste wird nicht mehr ausgeführt
                   list = stack = auto = undefiniert;
                   gib dies zurück;
            },
              deaktiviert: Funktion () {//Ob es deaktiviert wurde
 

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn