Hallo Michael_K,
ad 1: Ja
ad 2: Ein Generator kann einen weiteren Generator erzeugen und diesen iterieren, das geht. Die Aufgabe ist dann nur, die inneren Generatoren am Arbeiten zu halten, d.h. der innere Generator muss irgendeine Wertefolge erzeugen, die der äußere Generator mit einer Iterationsschleife abholt.
Tatsächlich ist das eine so häufige Aufgabe, dass JavaScript dafür den Syntaxzucker yield* anbietet.
const xyz = createSubGenerator();
// Entweder so:
yield* xyz;
// Oder so, wenn meine Abort-Idee beibehalten werden soll:
for (const value of xyz) {
if (yield value) break;
}
Oder anders - je nachdem, wie Du die Untersequenzen verarbeiten musst. Möglicherweise muss man noch feintunen, ich habe das jetzt ziemlich aus der Hüfte geschossen.
Der Teil, der die Laufzeit überwacht und nach zu langer Verarbeitung eine Runde in der Eventloop einschiebt, sollte unverändert bleiben können. Die ganze yielderrei dient ja nicht dazu, eine echte Wertefolge zu erzeugen, sondern Pausierungspunkte in der Coroutine zu ermöglichen. In PHP würde man das mit Fibers machen.
Aber ob Dir das alles was nützt? Ist html2canvas denn so designed, dass Du mit yield etwas anfangen kannst? Der yield muss ja direkt in der Generatorfunktion stecken. Eine Generatorfunktion, die html2canvas aufruft und dann in irgendwelchen Callbacks von html2canvas yield machen will, das geht nicht.
Grund: wenn ein yield stattfindet, muss der komplette Status der Generatorfunktion festgehalten werden. Dann endet sie. Wenn auf dem Generatorobjekt next() aufgerufen wird, wird der Status wiederhergestellt und die Ausführung fortgesetzt. Das geht aber nur, wenn der JavaScript-Code dafür passend übersetzt wurde. Und es geht gar nicht, wenn zwischen Generator und yield noch irgendwas auf dem Stack rumliegt.
Programmiere mal einen Iterator von Hand. Dann weißt Du, wie sehr man sich die Finger bricht, um so etwas von Hand zu realisieren. JavaScript muss deinen Generator unter der Haube in eine solche Struktur umsetzen.
Rolf
sumpsi - posui - obstruxi