Heim Web-Frontend js-Tutorial Lösung für das Problem der Blockierung von UI-Threads, das durch jQuery-synchronisiertes Ajax verursacht wird

Lösung für das Problem der Blockierung von UI-Threads, das durch jQuery-synchronisiertes Ajax verursacht wird

Aug 13, 2017 am 10:09 AM
ajax jquery 线程

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;
}
Nach dem Login kopieren

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);
});
Nach dem Login kopieren

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);
});
Nach dem Login kopieren

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 (&#39;aaaaaa&#39;);
?>
Nach dem Login kopieren

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:


$(&#39;.btn2&#39;).click(function(){
    $(&#39;.loadingicon&#39;).show();
    setTimeout(function(){
      $.ajax({
        url : &#39;p.php&#39;,
        async : false,
        success: function(data){
          $(&#39;.loadingicon&#39;).hide();
          alert(data);
        }
      });
    }, 0);
});
Nach dem Login kopieren

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 : &#39;p.php&#39;,
      //async : false,
      success: function(data){
        defer.resolve(data)
      }
    });
    return defer.promise();
}  

$(&#39;.btn3&#39;).click(function(){
    $(&#39;.loadingicon&#39;).show();
    $.when(getData3()).done(function(data){
      $(&#39;.loadingicon&#39;).hide();
      alert(data);
    });
});
Nach dem Login kopieren

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 : &#39;p.php&#39;,
      async : false,
      success: function(data){
        result = data;
      }
    });

    return result;
  }

  $(&#39;.btn1&#39;).click(function(){
    $(&#39;.loadingicon&#39;).show();
    var data = getData1();
    $(&#39;.loadingicon&#39;).hide();
    alert(data);
  });


  
  $(&#39;.btn2&#39;).click(function(){
    $(&#39;.loadingicon&#39;).show();
    setTimeout(function(){
      $.ajax({
        url : &#39;p.php&#39;,
        async : false,
        success: function(data){
          $(&#39;.loadingicon&#39;).hide();
          alert(data);
        }
      });
    }, 0);
  });



  function getData3(){
    var defer = $.Deferred();
    $.ajax({
      url : &#39;p.php&#39;,
      //async : false,
      success: function(data){
        defer.resolve(data)
      }
    });
    return defer.promise();
  }  

  $(&#39;.btn3&#39;).click(function(){
    $(&#39;.loadingicon&#39;).show();
    $.when(getData3()).done(function(data){
      $(&#39;.loadingicon&#39;).hide();
      alert(data);
    });
  });</script>
Nach dem Login kopieren

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!

Erklärung dieser Website
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

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

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

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Java-Tutorial
1657
14
PHP-Tutorial
1257
29
C#-Tutorial
1231
24
PHP und Ajax: Erstellen einer Autovervollständigungs-Vorschlags-Engine PHP und Ajax: Erstellen einer Autovervollständigungs-Vorschlags-Engine Jun 02, 2024 pm 08:39 PM

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? Wie verwende ich die PUT-Anfragemethode in jQuery? Feb 28, 2024 pm 03:12 PM

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

Wie erhalte ich Variablen aus der PHP-Methode mit Ajax? Wie erhalte ich Variablen aus der PHP-Methode mit Ajax? Mar 09, 2024 pm 05:36 PM

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:

jQuery-Tipps: Ändern Sie schnell den Text aller a-Tags auf der Seite jQuery-Tipps: Ändern Sie schnell den Text aller a-Tags auf der Seite Feb 28, 2024 pm 09:06 PM

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: &lt

Verwenden Sie jQuery, um den Textinhalt aller a-Tags zu ändern Verwenden Sie jQuery, um den Textinhalt aller a-Tags zu ändern Feb 28, 2024 pm 05:42 PM

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:

Gleichzeitige C++-Programmierung: Wie vermeidet man Thread-Aushungerung und Prioritätsumkehr? Gleichzeitige C++-Programmierung: Wie vermeidet man Thread-Aushungerung und Prioritätsumkehr? May 06, 2024 pm 05:27 PM

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.

PHP vs. Ajax: Lösungen zum Erstellen dynamisch geladener Inhalte PHP vs. Ajax: Lösungen zum Erstellen dynamisch geladener Inhalte Jun 06, 2024 pm 01:12 PM

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.

Gleichzeitige C++-Programmierung: Wie führt man Thread-Beendigung und -Abbruch durch? Gleichzeitige C++-Programmierung: Wie führt man Thread-Beendigung und -Abbruch durch? May 06, 2024 pm 02:12 PM

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

See all articles