Ich habe eine electron/node.js App, mit der ich Probleme habe. Insbesondere muss ich dem Benutzer ein Feedback über den Fortschritt einer langen Schleife synchroner Spawns geben, indem ich ein Element im DOM aktualisiere. Was tatsächlich angezeigt wird, ändert sich jedoch nicht während der Schleife. Sobald die gesamte Schleife abgeschlossen ist, wird das Element mit dem letzten max
Indexwert aktualisiert.DOM redraw wird von childProcess.spawnSync blockiert
function dosomething(index,callback) {
childProcess.spawnSync('app1',... //takes 1 second
childProcess.spawnSync('app2',... //takes 6 seconds, depends on app1 running 1st
console.log('working on: ' + index);
callback(index);
}
function dosomethingelse(index) {
$('#somediv').html(index); //update progress bar
console.log('displaying: ' + $('#somediv').html());
}
for(var i=0; i<max; i++){ //max is usually 10-100, loop takes 1 to 10 minutes
dosomething(i,dosomethingelse);
}
Wenn ich den Fortschritt html auf die Konsole Dump, es mit dem Index als Rückruf erhöht hat:
CONSOLE:
working on: 0
displaying: 0
working on: 1
displaying: 1
working on: 2
displaying: 2
...
Auch habe ich versucht, das div zu zwingen, neu zu zeichnen, indem Sie den folgenden Code nicht ausgeführt wird navis:
Von dem, was ich gelesen habe, macht die Verwendung von spawnSync meine binäre App im Sperrmodus auf Nodejs ausgeführt. Dies ist direkt gegen den nicht blockierenden Kern des Knotens, aber in meiner Situation absolut notwendig, da mein Kommandozeilenaufruf 6 Sekunden lang läuft und fast 100% CPU verbraucht. Wenn ich stattdessen den standardmäßigen asynchronen Spawn verwende, lande ich mit 50x 100% gleichzeitig ablaufenden Prozessen, die nach ein paar Minuten zur selben Zeit beendet werden. Auch hier gibt es keine Fortschrittsrückmeldung für den Benutzer. Ich verstehe nicht, warum mein Rückruf nicht abgeschlossen wird. Wenn ich die Funktionen so umschalte, dass dosomethingelse
zuerst mit einem dosomething
Callback aufgerufen wird, bekomme ich immer noch keine DOM-Updates.
Zwei andere Dinge, die ich versucht habe: npm sleep:
dosomething(i);
var sleep = require('sleep');
sleep.usleep(100);
dosomethingelse(i);
Und deasync:
var deasync = require('deasync');
deasync(dosomething(i));
dosomethingelse(i);
gleiches Ergebnis. Auch, wenn ich meine lang laufende dosomething
Funktion herausnehme und sie durch eine sleep.sleep(3)
ersetze, bekomme ich das gleiche Ergebnis. Der Knoten wechselt einfach von einer blockierenden Aufgabe zur nächsten, ohne die Benutzeroberfläche zu aktualisieren.
Ich habe darüber nachgedacht, einen Befehlszeilenspooler wie diesen zu verwenden: http://vicerveza.homeunix.net/~viric/soft/ts/, durch den alle meine schweren CPU-Aufgaben laufen und ihn dann jede Sekunde abfragen Aktualisiere meinen Fortschrittsbalken. Problem bei diesem Ansatz ist, dass es nicht plattformübergreifend ist (zumindest mit diesem Spooler). Ich muss mit dem Windows-Port kreativer werden. – UltrasoundJelly
Tun Sie es einfach async und fügen Sie es in eine Warteschlange ein? – mash
Der Versuch, das Chrome-DOM zu aktualisieren, das der Benutzer als Teil der Elektronen-App sieht. – UltrasoundJelly