Vielen Dank Mathias, für deine Antworten. Versuche diese mal zu beantworten:
Wie lange läuft das Script und warum braucht es so lange? Sind das etwa synchrone Input/Output-Operationen?
Nun ja, das Script dient zur Erzeugung von Stücklisten, sprich, aus einer sehr sehr großen Anzahl an Dateien (Teilen) soll anhand einer ausgelesenen Excel-Liste eine *.txt erstellt werden, wo nur ausgewählte Teile vorhanden sind. Und je nachdem wie groß der Ordner ist (kann auch nicht verkleinert werden durch Unterordner) oder wie "aktuell" die Daten sein müssen, kann es halt länger dauern. U.u. an die 1-2 Minuten
Ja, das ist normal. Der Browser setzt eine Änderung am DOM erst durch Layouting und Painting um, wenn der aktuelle Call-Stack abgearbeitet ist und der JavaScript-Interpreter zur Ruhe kommt bzw. mit dem nächsten geplanten Funktionaufruf weitermacht. Stichwort »JavaScript Event Loop«. Sprich: Dein JavaScript muss zur Ruhe kommen.
Ja, setTimeout bzw. setImmediate ist eine Möglichkeit. Eine andere ist das Erzwingen des Renderings durch die Abfrage von offsetWidth oder einer anderen Eigenschaft, dessen Wert der Browser erst durch Layouting korrekt zurückliefern kann.
Das heißt also, ich muss in dem Script Pausen erzwingen, so dass das Script, wie du sagst, zur Ruhe kommt und Zeit bekommt, die Änderungen im Design vorzunehmen.
Nun aber die Frage dazu: Welche Funktionen müsste ich mittels settimeout() starten lassen? Meine Fortschritt_Anzeige() (oder in deinem Falle renderStatus()) oder die anderen Funktionen (one, two, three, ...)?
Das settimeout() dient doch nur dazu, eine Funktion nach einer gewissen Zeit starten zu lassen, aber in der Zeit wird doch keine "Pause" verursacht um das Script design-mäßig zu verändern oder?
Das lässt sich z.B. mithilfe einer Queue lösen, die abgearbeitet wird:
var one = function () {…};
var two = function () {…};
var three = function () {…};
var renderStatus = function () {…};var queue = [one, two, three];
var loop = function () {
var func = queue.shift();
if (func) {
func(); // Führe Schritt aus
renderStatus(); // Erstatte Bericht
setTimeout(loop, 1); // Beende Call-Stack, erzeuge neuen
// Jetzt kann der Browser rendern
}
};
loop();
Ok, also müsste ich meine ganzen Funktionen in diese loop() packen, was aussehen würde wie:
~~~javascript
function init()
{
var one = function Excel_Tabelle_Laden( Wert1 ) {…};
var two = function Leere_Eintraege_Loeschen( Wert1 ) {…};
var three = function Daten_konvertieren( Wert1 ) {…};
var renderStatus = function Fortschritt_Anzeige( Parameter1 ) {…};
//--> Und wie bekomm ich aus den oben genannten Funktionen meine Werte zurück?
//--> Weil vorher hatte ich es wie folgt:
// infile = function Excel_Tabelle_Laden( Ausgangswerte )
// infile = function Leere_Eintraege_Loeschen( infile )
// infile = function Daten_konvertieren( infile )
// ...
//--> also die zurückgegebenen Werte wurden für die weiteren Funktionen benutzt
var queue = [one, two, three];
var loop = function () {
var func = queue.shift();
if (func) {
func(); // Führe Schritt aus
renderStatus(); // Erstatte Bericht
setTimeout(loop, 1); // Beende Call-Stack, erzeuge neuen
// Jetzt kann der Browser rendern
}
};
loop();
};
Und der untere Teil bewirkt, dass er z.B. mir die Excel-Tabelle ausliest,nach dem Beenden in die Fortschritt_Anzeige() springt und da das Design ändert und danach,nach 1ms den "alten" Aufruf beendet und nen neuen aufruft? Hoffe ich hab es so richtig verstanden :)
LG Romero