FrageVor einigen Tagen stieß ich beim Schreiben von HTML-Seiten mit JavaScript auf ein merkwürdiges Problem: Die Funktion, die ich erreichen möchte, besteht darin, dass Benutzer über das Popup-Fenster „confirm()“ verschiedene Anforderungen auswählen können. Nach jeder Auswahl wird das Auswahlergebnis vorübergehend auf der Seite ausgegeben. Nach der letzten Auswahl werden die Optionen sofort zur Verarbeitung an das Backend übergeben. Der Code ähnelt: var Schritt1 = bestätigen("Schritt1 ausführen?"); $('#result').html($('#result').html() + "\n" + Schritt1); var Schritt2 = bestätigen("Schritt2 ausführen?"); $('#result').html($('#result').html() + "\n" + Schritt2); var step3 = bestätigen("Schritt 3 ausführen?"); $('#result').html($('#result').html() + "\n" + Schritt3); sende(Schritt1, Schritt2, Schritt3); Nach dem Ausführen des Codes stellte ich jedoch fest, dass jedes Mal, wenn die Bestätigungsfunktion ausgeführt wurde und der Benutzer eine Option auswählte, die Seite nicht aktualisiert wurde und die Ergebnisse von Schritt 1 und Schritt 2 nicht in Echtzeit auf der Seite aktualisiert wurden, sondern zusammen mit Schritt 3 im letzten Schritt angezeigt wurden. Ich habe dann alert() und prompt() ausprobiert, zwei Dialogfeldfunktionen ähnlich wie confirm, und die Situation war dieselbe. Sie übersprangen das Rendern der Seite und wurden zuerst ausgeführt. An dieser Stelle gibt es eine noch seltsamere Situation. Nachdem wir einem Div einen Wert zugewiesen haben, weisen wir sofort auf den Inhalt dieses Div hin. Wir werden feststellen, dass die Warnung den richtigen Inhalt anzeigt, aber der Inhalt des Div wird nicht aktualisiert und blockiert, bis wir auf OK klicken. Wie in der Abbildung gezeigt: Die drei Funktionen Alarm, Eingabeaufforderung und Bestätigung sind ähnlich. Als Nächstes verwenden wir den einfachsten Alarm als Beispiel. analysierenBevor wir dieses Problem lösen, müssen wir zunächst verstehen, was es verursacht. Dazu müssen wir mit dem JavaScript-Thread-Modell beginnen. Die JavaScript-Engine wird in einem einzigen Thread ausgeführt. Der Browser verfügt immer nur über einen Thread, der das JavaScript-Programm ausführt. Die ursprüngliche Absicht bestand darin, Konflikte in gemeinsam genutzten Ressourcen wie DOM zu reduzieren. Ein einzelner Thread wird jedoch immer auf ein Problem stoßen, d. h. das Blockieren eines bestimmten Codeabschnitts führt dazu, dass alle nachfolgenden Aufgaben verzögert werden. Und da JavaScript häufig das Seiten-DOM bedienen und HTTP-Anfragen senden muss, dauern diese E/A-Vorgänge normalerweise lange. Sobald sie blockiert sind, führt dies zu einer sehr schlechten Benutzererfahrung. So wurde die Ereignisschleife erstellt. JavaScript stellt alle asynchronen Operationen oder Operationen mit I/O-Blockierung in eine Ereigniswarteschlange, führt den synchronen CPU-Code sequenziell aus und liest dann die asynchronen Ereignisse in der Ereigniswarteschlange und führt sie sequenziell aus, wenn die JavaScript-Engine keinen synchronen Code hat und die CPU im Leerlauf ist. Zu diesen Veranstaltungen gehören:
lösenNachdem wir nun das Prinzip verstanden haben, wissen wir, wie wir dieses Problem lösen können. Lassen Sie uns dieses Problem analysieren: 1. Da es sich bei der Seitendarstellung um eine DOM-Operation handelt, wird sie von der JavaScript-Engine in die Ereigniswarteschlange gestellt. 2. alert() ist eine integrierte Funktion von Window und wird als synchroner CPU-Code betrachtet; 3. Die JavaScript-Engine führt zuerst den synchronen Code aus und das Warn-Popup-Fenster wird zuerst angezeigt. 4. alert verfügt über eine spezielle Blockierungseigenschaft und blockiert die Ausführung der JavaScript-Engine. 5. Klicken Sie in der Warnung auf „OK“. JavaScript wird nicht mehr blockiert. Nach der Ausführung des synchronen Codes wird der DOM-Vorgang in der Ereigniswarteschlange gelesen und das Rendern der Seite ist abgeschlossen. Die oben genannten Gründe führen zu dem seltsamen „Problem mit der Alarmausführungsreihenfolge“. Wir können das Rendern der Seite nicht in einen synchronen Vorgang umwandeln, daher müssen wir alert() in asynchronen Code umwandeln, damit er nach dem Rendern der Seite ausgeführt werden kann. Für diese Lösung stehen uns zwei Methoden zur Verfügung: Ersetzen Sie die Funktion Alert()Betrachten wir zunächst den Austausch der Funktionalität der Warnfunktion. Tatsächlich ersetzen wir in den meisten Fällen Warnungen nicht, weil sie nicht der erwarteten Ausführungsreihenfolge entsprechen, sondern weil sie zu hässlich sind und keine Verschönerungen unterstützen. Sie können sich vorstellen, wie unpassend es ist, wenn auf einer Website mit einem bestimmten Thema plötzlich ein graues und eintöniges Dialogfeld auftaucht. Wir können das modale Modul von Bootstrap in Betracht ziehen. Bootstrap wird auf den meisten Websites verwendet und die Einführung eines weiteren modalen Moduls wird keine großen Auswirkungen haben. Wir verwenden Modal, um ein Popup-Dialogfeld zu erstellen. Mit den Modalmethoden modal('toggle')/modal('show')/modal('hide') können wir die Sichtbarkeit des Modals problemlos steuern. Nach dem Ersetzen des Dialogfelds müssen wir noch das Problem der nachfolgenden Codeausführung lösen. Wenn wir die Warnfunktion verwenden, wird der Code nach dem Klicken auf „OK“ weiter ausgeführt. Diese Funktion ist jedoch bei Verwendung unseres benutzerdefinierten Dialogfelds nicht verfügbar. Wir müssen den nachfolgenden Code an die Klickschaltfläche des Dialogfelds binden. Dies erfordert die Verwendung des Es ist auch wichtig zu beachten, dass die neue Funktion den Inhalt zum Schließen des modalen Dialogfelds enthalten sollte. Natürlich können wir es weiter optimieren und eine Funktion abstrahieren, die anstelle der Warnfunktion ein Dialogfeld öffnet. Das Beispiel lautet wie folgt: window.alert = Funktion (Nachricht, Rückruffunktion) { $('#alertContent').html(Nachricht); $('#modal').anzeigen(); $('#Bestätigungsschaltfläche').beimKlicken(Funktion () { $('#modal').ausblenden(); Rückruffunktion(); }); }; Auf diese Weise rufen wir die neue Warnfunktion auf, wenn wir ein Popup-Fenster benötigen, übergeben callbackFunc und führen die nachfolgende Arbeit darin aus. setTimeOut-FunktionNatürlich ist nicht jeder bereit, ein neues Dialogfeld zu verwenden, um das Dialogfeld der Warnfunktion zu ersetzen. Ich habe immer das Gefühl, dass die obige Methode nicht besonders elegant ist. In dieser Hinsicht können wir eine andere Methode verwenden, um dieses Problem zu lösen. Frontend-Studenten sollten mit der Funktion setTimeout() vertraut sein. Mit ihr können Sie die Ausführung bestimmten Codes verzögern. Was Code mit verzögerter Ausführung betrifft, stellt die JavaScript-Engine den Code immer in die Ereigniswarteschlange, prüft, ob die Ausführungszeit erreicht ist, und führt ihn dann zum entsprechenden Zeitpunkt aus. Wenn Code in die Ereigniswarteschlange eintritt, bedeutet dies, dass der Code wie das Seiten-Rendering-Ereignis asynchron wird. Da die Ereigniswarteschlange geordnet ist, können wir die Warnfunktion nach dem Rendern der Seite implementieren, wenn wir „setTimeout“ zur Verzögerung der Ausführung verwenden. Der Funktionsprototyp von setTimeout ist setTimeout(code, msec), wobei code der Code oder die Funktion ist, die asynchron gemacht werden soll, und msec die Verzögerungszeit in Millisekunden ist. Hier ist keine Verzögerung erforderlich, es muss lediglich asynchron erfolgen, sodass wir msec auf 0 setzen können. In ähnlicher Weise müssen wir auch den Code nach der Warnung verarbeiten und ihn zusammen mit der Warnung in setTimeout für die asynchrone Ausführung einfügen. Auf diese Weise wird der Code zu setTimeout("alert('msg');doSomething();", 0);. Wenn Sie meinen, der Code sei nicht schön genug oder die Zeichenfolge sei schwer zu handhaben, können Sie den nachfolgenden Code in eine Funktion kapseln und in doSomething() einfügen. ZusammenfassungIn den beiden oben genannten Lösungen werden JavaScript-Rückruffunktionen verwendet. Erstere verwendet die Funktion als Parameter von alert und bindet sie an das Onclick-Ereignis von DOM, während letztere setTimeout verwendet, um die Funktion in eine asynchrone Ausführung umzuwandeln. JavaScript-Rückruffunktionen sind zwar sehr leistungsstark und einfach zu verwenden, es gibt jedoch ein verstecktes Problem, nämlich das Problem verschachtelter Rückrufe. Einschichtige Rückrufe sind leicht zu verstehen, aber wenn Sie eine Situation wie meine Anforderungen implementieren möchten, bei der mehrere Warnungen und Seitendarstellungen nacheinander ausgeführt werden, werden Sie möglicherweise mit der „Rückrufhölle“ konfrontiert. Die Funktion in der Onclick-Ereignisbindung muss in der Onclick-Funktion verschachtelt sein, und in SetTimeout ist eine weitere SetTimeout-Anweisung erforderlich. Sobald ein Problem auftritt, ist die Fehlerbehebung schwieriger. Oben finden Sie eine ausführliche Erläuterung des Problems der Ausführungsreihenfolge der JavaScript-Alarmfunktion. Weitere Informationen zum Problem der Ausführungsreihenfolge der JavaScript-Alarmfunktion finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: Erfahrung in der Lösung von Tomcat-Speicherüberlaufproblemen
Inhaltsverzeichnis Vorwort Standard-SFC-Schreibme...
Problembeschreibung Wenn VMware Workstation eine ...
einführen GitLab CE oder Community Edition ist ei...
CHAR- und VARCHAR-Typen sind ähnlich und untersch...
Nun, vielleicht sind Sie ein Design-Guru, oder vie...
Szenario Eine aktuelle Anforderung ist eine h5-Se...
In diesem Artikel finden Sie den spezifischen Cod...
Virtuelle Maschinen sind eine sehr praktische Tes...
Zunächst müssen Sie verstehen, warum Sie Verbindu...
In diesem Artikel wird der detaillierte Vorgang z...
Ändern Sie den Standardstil der Auswahl, normalerw...
1. Skip-Grant-Tables zur Datei my.ini hinzufügen ...
<br />Originaltext: http://andymao.com/andy/...
Deinstallieren Sie MariaDB CentOS7 installiert st...