Rolf B: setTimeout(), windows.setInterval() → Promises?

Beitrag lesen

Hallo Raketenwilli,

da steht an mehreren Stellen deutlich, dass setInterval sich nicht in ein Promise umbauen lässt. Weil ein Promise nur einmal resolved.

Mit setTimeout geht das, weil setTimeout nur einmal feuert:

function delay(millisecs, data) {
   return new Promise((function(resolve,reject) {
      setTimeout(resolve, millisecs, data);
   });
}

delay(2000, "Hallo")
.then(huhu => console.log(huhu));

gibt nach 2s "Hallo" aus.

SetInterval könnte man über einen asynchronen Generator realisieren, steht da, aber alle Beispiele verwenden unter der Haube setTimeout um zum nächsten Schritt zu kommen - mit allen Nachteilen. Mit setInterval bekommt man glattere Zeitabstände - aber man kann den callback von setInterval nicht auf ein Promise mappen.

Aber ob ich mir hier jetzt mit einem Beispiel für einen asynchronen Generator Freude mache?

Denkbares Szenario: Man verwendet einen Intervallgeber, der von 1 bis 50 ticken soll, in 500ms Abständen. Diese 50 Werte möchte man konsumieren, aber NICHT mit einem setInterval-Callback, sondern eingebettet in eine andere Verarbeitung, d.h. man möchte auf den Tick warten, dann möchte man etwas tun, und wieder auf den Tick warten. Als Komplikation könnte man ergänzen, dass dieses "etwas tun" mal länger und mal kürzer dauert, und auch mal länger dauern kann als der Abstand zwischen zwei Ticks, und in dem Fall sollen die "ausgelassenen Ticks" möglichst schnell nachgeholt werden.

Es wäre doch schick, wenn die Verarbeitung ganz stumpf so aussehen könnte:

for (let seq of sequenceGenerator(1,50) {
   // do something with seq
}

Und ja, das geht. Man muss noch etwas ergänzen:

for await (let seq of sequenceGenerator(1,50) {
   // do something with seq
}

Und nun kann man den sequenceGenerator als asynchronen Generator implementieren.

async function* sequenceGenerator(start, end) {
   // ...some magic control
   yield counter;
}

Im Inneren des sequenceGenerators kann man mit setTimeout arbeiten, um die Ticks abzuwarten, aber dann hat man ggf. zeitliche Unregelmäßigkeiten. Besser ist setInterval.

Das Beispiel steht hier: https://jsfiddle.net/Rolf_b/raLz483h/

Ich muss aber jetzt weg vom Gerät, eine Erklärung folgt später.

Rolf

--
sumpsi - posui - obstruxi