


Lösung für das Problem der Blockierung von UI-Threads, das durch jQuery-synchronisiertes Ajax verursacht wird
Dieser Artikel stellt hauptsächlich das Problem der UI-Thread-Blockierung vor, das durch jQuery-synchronisiertes Ajax verursacht wird. Es hat einen bestimmten Referenzwert.
Wie das Sprichwort sagt, wenn Sie es nicht tun Suche den Tod, du wirst heute nicht sterben und eine relativ dumme Funktion geschrieben, die durch synchronisiertes Ajax verursacht wird.
Der Grund dafür ist, dass es auf der Seite mehrere ähnliche asynchrone Anforderungsaktionen gibt. Um die Wiederverwendbarkeit des Codes zu verbessern, habe ich eine Funktion namens getData gekapselt, die verschiedene Parameter empfängt und nur für den Datenabruf verantwortlich ist und dann die Daten zurückgeben. Die grundlegende Logik lautet wie folgt:
function getData1(){ var result; $.ajax({ url : 'p.php', async : false, success: function(data){ result = data; } }); return result; }
Der Ajax hier kann nicht asynchron sein, sonst wurde dem Ergebnis bei der Rückkehr der Funktion kein Wert zugewiesen, und Es wird ein Fehler auftreten. Also habe ich async:false hinzugefügt. Es scheint, als gäbe es kein Problem. Ich kann die Daten normal abrufen, indem ich diese Funktion aufrufe.
$('.btn1').click(function(){ var data = getData1(); alert(data); });
Als nächstes muss ich eine weitere Funktion hinzufügen. Da die Ajax-Anfrage zeitaufwändig ist, muss ich einen Ladeeffekt auf der Seite haben, bevor ich die Anfrage stelle , das heißt, es wird ein „Laden“-GIF-Bild angezeigt, das jeder gesehen haben muss. Meine Verarbeitungsfunktion sieht also so aus:
$('.btn1').click(function(){ $('.loadingicon').show(); var data = getData1(); $('.loadingicon').hide(); alert(data); });
Zeigen Sie das Ladebild vor der Anfrage an und blenden Sie es aus, nachdem die Anfrage abgeschlossen ist. Es scheint kein Problem zu geben. Um den Effekt deutlich zu sehen, schläft mein p.php-Code 3 Sekunden lang wie folgt:
<?php sleep(3); echo ('aaaaaa'); ?>
Als ich ihn ausführte, trat jedoch ein Problem auf Ich habe auf die Schaltfläche geklickt, es hat nicht funktioniert. Das Ladebild erscheint wie erwartet, aber die Seite reagiert überhaupt nicht. Nach langer Fehlerbehebung habe ich den Grund gefunden, der async:false ist.
Der Rendering-Thread (UI) des Browsers und der JS-Thread schließen sich gegenseitig aus. Wenn zeitaufwändige JS-Vorgänge ausgeführt werden, wird das Rendern der Seite blockiert. Es gibt kein Problem, wenn wir asynchrones Ajax ausführen, aber wenn es auf eine synchrone Anforderung eingestellt ist, werden andere Aktionen (der Code hinter der Ajax-Funktion und der Rendering-Thread) gestoppt. Selbst wenn meine DOM-Operationsanweisung im Satz steht, bevor die Anforderung initiiert wird, blockiert diese Synchronisierungsanforderung den UI-Thread „schnell“, ohne ihm Zeit zur Ausführung zu geben. Aus diesem Grund schlägt der Code fehl.
setTimeout löst das Blockierungsproblem
Da wir nun verstanden haben, wo das Problem liegt, wollen wir eine Lösung finden. Um zu verhindern, dass die synchrone Ajax-Anfrage den Thread blockiert, dachte ich an setTimeout, füge den Anforderungscode in sestTimeout ein und lasse den Browser einen Thread neu starten, um zu funktionieren. Wäre das Problem nicht gelöst? Seitdem sieht mein Code so aus:
$('.btn2').click(function(){ $('.loadingicon').show(); setTimeout(function(){ $.ajax({ url : 'p.php', async : false, success: function(data){ $('.loadingicon').hide(); alert(data); } }); }, 0); });
Der zweite Parameter von setTimeout ist auf 0 gesetzt und der Browser setzt ihn innerhalb einer festgelegten Mindestzeit. später hingerichtet. Egal was passiert, lassen Sie es uns zuerst ausführen und sehen.
Das Ergebnis-Ladebild wird angezeigt, aber! ! ! Warum bewegt sich das Bild nicht? Es ist offensichtlich ein animiertes GIF. Zu diesem Zeitpunkt dachte ich schnell, dass die Synchronisierungsanforderung zwar verzögert war, den UI-Thread jedoch während seiner Ausführung blockieren würde. Diese Blockierung ist so großartig, dass sich selbst das GIF-Bild nicht bewegt und wie ein statisches Bild aussieht.
Die Schlussfolgerung liegt auf der Hand. SetTimeout behandelt die Symptome, aber nicht die Grundursache. Dies ist gleichbedeutend damit, dass die Synchronisierungsanforderung „leicht“ asynchron ist und dann immer noch in einen Synchronisierungsalbtraum gerät und den Thread blockiert. Der Plan scheiterte.
Es ist Zeit, Deferred zu verwenden
Nach Version 1.5 führte jQuery das Deferred-Objekt ein, das einen sehr praktischen verallgemeinerten asynchronen Mechanismus bietet. Einzelheiten finden Sie in diesem Artikel http://www.jb51.net/article/54762.htm.
Also habe ich den Code mit einem Deferred-Objekt wie folgt umgeschrieben:
function getData3(){ var defer = $.Deferred(); $.ajax({ url : 'p.php', //async : false, success: function(data){ defer.resolve(data) } }); return defer.promise(); } $('.btn3').click(function(){ $('.loadingicon').show(); $.when(getData3()).done(function(data){ $('.loadingicon').hide(); alert(data); }); });
Sie können sehen, dass ich async:false in der Ajax-Anfrage entfernt habe , auch Das heißt, diese Anfrage ist wieder asynchron. Bitte beachten Sie auch diesen Satz in der Erfolgsfunktion: defer.resolve(data) Die Auflösungsmethode des Deferred-Objekts kann einen Parameter eines beliebigen Typs übergeben. Dieser Parameter kann in der Methode done abgerufen werden, sodass die von uns asynchron angeforderten Daten auf diese Weise zurückgegeben werden können.
Zu diesem Zeitpunkt ist das Problem gelöst. Aufgeschobene Objekte sind so leistungsstark und praktisch, dass wir sie nutzen können.
Alle meine Testcodes lauten wie folgt:
<button class="btn1">async:false</button> <button class="btn2">setTimeout</button> <button class="btn3">deferred</button> <img class="loadingicon" style="position:fixed;left:50%;top:50%;margin-left:-16px;margin-top:-16px;display:none;" src="loading2.gif" alt="正在加载" /> <script> function getData1(){ var result; $.ajax({ url : 'p.php', async : false, success: function(data){ result = data; } }); return result; } $('.btn1').click(function(){ $('.loadingicon').show(); var data = getData1(); $('.loadingicon').hide(); alert(data); }); $('.btn2').click(function(){ $('.loadingicon').show(); setTimeout(function(){ $.ajax({ url : 'p.php', async : false, success: function(data){ $('.loadingicon').hide(); alert(data); } }); }, 0); }); function getData3(){ var defer = $.Deferred(); $.ajax({ url : 'p.php', //async : false, success: function(data){ defer.resolve(data) } }); return defer.promise(); } $('.btn3').click(function(){ $('.loadingicon').show(); $.when(getData3()).done(function(data){ $('.loadingicon').hide(); alert(data); }); });</script>
PS: Ist Firefox optimiert?
Die oben genannten Probleme wurden in Chrome und IE9 getestet und die Schlussfolgerungen sind konsistent. Aber als ich es in Firefox getestet habe, blockierte synchronisiertes Ajax den UI-Thread nicht, was bedeutet, dass dieses Problem überhaupt nicht besteht. Ich habe es mit anderen Codes getestet. Daran besteht kein Zweifel. Eine mögliche Vermutung ist, dass Firefox synchronisiertes Ajax optimiert hat. Ich habe noch nicht herausgefunden, was das ist. Wenn es jemand weiß, gebt mir bitte einen Rat.
Das obige ist der detaillierte Inhalt vonLösung für das Problem der Blockierung von UI-Threads, das durch jQuery-synchronisiertes Ajax verursacht wird. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen











Erstellen Sie eine Engine für Autovervollständigungsvorschläge mit PHP und Ajax: Serverseitiges Skript: Verarbeitet Ajax-Anfragen und gibt Vorschläge zurück (autocomplete.php). Client-Skript: Ajax-Anfrage senden und Vorschläge anzeigen (autocomplete.js). Praktischer Fall: Fügen Sie ein Skript in die HTML-Seite ein und geben Sie die Kennung des Sucheingabeelements an.

Wie verwende ich die PUT-Anfragemethode in jQuery? In jQuery ähnelt die Methode zum Senden einer PUT-Anfrage dem Senden anderer Arten von Anfragen, Sie müssen jedoch auf einige Details und Parametereinstellungen achten. PUT-Anfragen werden normalerweise zum Aktualisieren von Ressourcen verwendet, beispielsweise zum Aktualisieren von Daten in einer Datenbank oder zum Aktualisieren von Dateien auf dem Server. Das Folgende ist ein spezifisches Codebeispiel, das die PUT-Anforderungsmethode in jQuery verwendet. Stellen Sie zunächst sicher, dass Sie die jQuery-Bibliotheksdatei einschließen. Anschließend können Sie eine PUT-Anfrage senden über: $.ajax({u

Die Verwendung von Ajax zum Abrufen von Variablen aus PHP-Methoden ist ein häufiges Szenario in der Webentwicklung. Durch Ajax kann die Seite dynamisch abgerufen werden, ohne dass die Daten aktualisiert werden müssen. In diesem Artikel stellen wir vor, wie man Ajax verwendet, um Variablen aus PHP-Methoden abzurufen, und stellen spezifische Codebeispiele bereit. Zuerst müssen wir eine PHP-Datei schreiben, um die Ajax-Anfrage zu verarbeiten und die erforderlichen Variablen zurückzugeben. Hier ist ein Beispielcode für eine einfache PHP-Datei getData.php:

Titel: jQuery-Tipps: Ändern Sie schnell den Text aller Tags auf der Seite. In der Webentwicklung müssen wir häufig Elemente auf der Seite ändern und bedienen. Wenn Sie jQuery verwenden, müssen Sie manchmal den Textinhalt aller a-Tags auf der Seite gleichzeitig ändern, was Zeit und Energie sparen kann. Im Folgenden wird erläutert, wie Sie mit jQuery den Text aller Tags auf der Seite schnell ändern können, und es werden spezifische Codebeispiele angegeben. Zuerst müssen wir die jQuery-Bibliotheksdatei einführen und sicherstellen, dass der folgende Code in die Seite eingefügt wird: <

Titel: Verwenden Sie jQuery, um den Textinhalt aller Tags zu ändern. jQuery ist eine beliebte JavaScript-Bibliothek, die häufig zur Verarbeitung von DOM-Operationen verwendet wird. Bei der Webentwicklung müssen wir häufig den Textinhalt des Link-Tags (eines Tags) auf der Seite ändern. In diesem Artikel wird erläutert, wie Sie mit jQuery dieses Ziel erreichen, und es werden spezifische Codebeispiele bereitgestellt. Zuerst müssen wir die jQuery-Bibliothek in die Seite einführen. Fügen Sie den folgenden Code in die HTML-Datei ein:

Um Thread-Aushunger zu vermeiden, können Sie faire Sperren verwenden, um eine faire Zuweisung von Ressourcen sicherzustellen, oder Thread-Prioritäten festlegen. Um die Prioritätsumkehr zu lösen, können Sie die Prioritätsvererbung verwenden, um die Priorität des Threads, der die Ressource enthält, vorübergehend zu erhöhen, oder die Sperrenerhöhung verwenden, um die Priorität des Threads zu erhöhen, der die Ressource benötigt.

Ajax (Asynchronous JavaScript and XML) ermöglicht das Hinzufügen dynamischer Inhalte, ohne die Seite neu laden zu müssen. Mit PHP und Ajax können Sie eine Produktliste dynamisch laden: HTML erstellt eine Seite mit einem Containerelement und die Ajax-Anfrage fügt die Daten nach dem Laden zum Element hinzu. JavaScript verwendet Ajax, um über XMLHttpRequest eine Anfrage an den Server zu senden, um Produktdaten im JSON-Format vom Server abzurufen. PHP nutzt MySQL, um Produktdaten aus der Datenbank abzufragen und in das JSON-Format zu kodieren. JavaScript analysiert die JSON-Daten und zeigt sie im Seitencontainer an. Durch Klicken auf die Schaltfläche wird eine Ajax-Anfrage zum Laden der Produktliste ausgelöst.

Zu den Thread-Beendigungs- und Abbruchmechanismen in C++ gehören: Thread-Beendigung: std::thread::join() blockiert den aktuellen Thread, bis der Ziel-Thread die Ausführung abschließt. std::thread::detach() trennt den Ziel-Thread von der Thread-Verwaltung. Thread-Abbruch: std::thread::request_termination() fordert den Ziel-Thread auf, die Ausführung zu beenden; std::thread::get_id() erhält die Ziel-Thread-ID und kann mit std::terminate() verwendet werden, um das Ziel sofort zu beenden Faden. Im tatsächlichen Kampf ermöglicht request_termination() dem Thread, den Zeitpunkt der Beendigung zu bestimmen, und join() stellt dies in der Hauptzeile sicher
