0

Ich mache (in JavaScript/jQuery) schwere Berechnungen. Das Problem ist, dass diese Berechnungen den UI-Thread blockieren und ich (versucht und) kann keinen Weg finden, dies zu vermeiden.Schwere JavaScript-Berechnungen Block

Einige Anforderungen:

  • Ich kann nicht Webworkers
  • Die Berechnungen verwenden, um auf Client-Seite sein muss (ich kann nicht einen AJAX-Aufruf zu tun, sie auf Server-Seite machen)

Ich bin ein Android-Programmierer, damit ich weiß, wie man das in Java macht (Thread starten, Berechnungen machen, Daten an UI-Thread senden) und so versuche ich, das Gleiche hier zu tun.

Also diese schweren Berechnungen können nur eine aktive Instanz haben (ich werde ein GIF machen, um den Benutzer zu beraten, er kann das nicht noch einmal vor diesem Ende starten), also muss nicht mehrere Anrufe verwalten (Ende zuletzt, neu starten). Hier

ist der Code:

var datas = []; // 10000 datas here 
function sortBy(param, paramType, order) { 
    var newArray = JSON.parse(JSON.stringify(datas)); 

    window.setTimeout(function(){ 
     var end = false; 
     for (var i = newArray.length - 1; i > 0 && !end; i--) { 
      end = true; 
      for (var j = 0; j < i - 1; j++) { 
       var sort = false; 

       if (paramType.localeCompare("str") == 0) { 
        if (newArray[j + 1][param].localeCompare(newArray[j][param]) < 0 && order.localeCompare("up") == 0) { 
         sort = true; 
        } else if (newArray[j + 1][param] > newArray[j][param] && order.localeCompare("down") == 0) { 
         sort = true; 
        } 
       } else if (paramType.localeCompare("nbr") == 0) { 
        if ((newArray[j + 1][param] - newArray[j][param]) < 0 && order.localeCompare("up") == 0) { 
         sort = true; 
        } else if ((newArray[j + 1][param] - newArray[j][param]) > 0 && order.localeCompare("down") == 0) { 
         sort = true; 
        } 
       } 

       if (sort) { 
        var tmp = newArray[j + 1]; 
        newArray[j + 1] = newArray[j]; 
        newArray[j] = tmp; 
        end = false; 
       } 
      } 
     } 

     datas = newArray; 
    }, 0); 
} 

Ich Sortier Daten (und für vermeiden Daten Neuladen vom Server für Handy, es ist, warum kann ich nicht diese Seite auf dem Server machen).

Ich habe versucht, das Array in der Funktion zu kopieren (vollständige Kopie, keine Referenz), weil ich dachte, dass die ursprüngliche Variable, die die Daten enthält, weil sie nicht in einer Funktion sind, auf dem UIhread und Der Zugriff auf die Funktion ruft den UI-Thread auf. => funktioniert nicht. (und damit liege ich falsch).

ich die Berechnungen in einem setTimout({computations}, 0) zu starten versuchte, wie Sie sehen können, das war eine Lösung, die ich sehr viel Zeit auf anderen Stack-Überlauf mit ähnlichen Fragen sehen =>nicht zu funktioniert.

Ich laufe in einer grundlegenden JavaScript-Umgebung, die einzige Bibliothek, die ich benutze, ist jQuery.

Also, ist hier ein Weg, um diese Berechnungen in einem anderen Thread (oder so ähnlich) zu arbeiten, oder mehr global, nicht UI-Thread blockieren?

+1

Werfen Sie einen Blick [hier] (http://StackOverflow.com/A/10344560/27414), wo der Vorschlag ist, die Hintergrundarbeit in Stücke zu zerlegen, mit Pausen dazwischen für die UI zu aktualisieren. –

+0

Warum können Sie Web Worker nicht genau verwenden? –

+0

@AkshatMahajan, weil nicht mit allen Geräten/Browser kompatibel sind. – Lucsartes

Antwort

3

Javascript ist single-threaded. Sofern Sie keinen Worker verwenden, besteht Ihre einzige Möglichkeit darin, die Berechnung in Teile aufzuteilen. Führen Sie einen Teil der Berechnung aus und verwenden Sie dann setImmediate oder setTimeout, um das nächste Stück zu planen. Dies gibt der Benutzeroberfläche Zeit für die Ausführung und verhindert die gefundene Blockierung.

Verwandte Themen