Inhaltsübersicht: poll()
Funktionen mit Rückrufen sind verfügbar; Ich habe keine nativen Versprechungen gefunden. Ich habe versucht, einige ohne Erfolg anzupassen. Das Problem, das ich noch nicht gelöst habe, ist, dass, wenn die erste Instanz der von setTimeout aufgerufenen Funktion ohne Rückkehr endet, die .then()
, die darauf wartet, die Beendigung als false
und reject()
sieht. then()
beendet und hört nicht auf spätere Rückgaben.Wie kann ich `.then()` lange genug am Leben halten, um eine Polling-Funktion mit nativen Versprechungen zu erhalten?
Frage: Wie am besten helfen, die Funktion bleiben für spätere Rücksendungen mit resolve()
oder reject()
?
Der Rest dieses Beitrags ist Detail. Lesen Sie, was hilft.
Verfügbare Pollfunktionen: Ich mag (https://stackoverflow.com/users/1249219/om-shankar) Om Shankars Antwort in Calling a function every 60 seconds. David Walshs Umfrage() ist sehr ähnlich (um https://davidwalsh.name/essential-javascript-functions). Beide verwenden Rückrufe und funktionieren gut. Ich fand poll in javascript , die eine poll()
mit bluebird
-only verspricht.
Hier ist mein Versuch, mit nativen Versprechen zu implementieren.
/**
* poll - checks repeatedly whether a condition exists. When the condition
* exists, returns a resolved standard promise. When it has checked
* long enough, returns a rejected standard promise.
* @param {function} fn - a caller-supplied synchronous function that
* detects a condition in the environment. Returns true if the
* condition exists; otherwise false.
* @param {number} timeout - maximum number of milliseconds
* the caller wants to check param fn();
* reject() the promise at the expiration of param timeout.
* @param {number} interval - minimum number of milliseconds between
* calls to param fn(); resolve() the promise when param fn() first
* reports true.
* @return {promise} - resolved when param fn() returns true;
* rejected if param timeout expires without param fn() returning true
*/
function poll(fn, timeout, interval) {
let endTime = Number(new Date()) + (timeout || 2000)
interval = interval || 250
return Promise.resolve *2
.then(() => { *3
(function p(fn, endTime, interval) {
if (fn()) { return Promise.resolve("Condition is satisfied.") } *4
else {
if (Number(new Date()) <= endTime) {) *5
window.setTimout(p, interval, fn, endTime, interval) *6
}
else {
return Promise.reject("Past endTime; condition not satisfied")
}
}
}()) *7
}) *8
}
Erwartete Nutzung:
function waitIsOver() { return (<desired condition exists>) }
poll(waitIsOver, 2000, 250) *1
Die Art, wie ich denke, das läuft (mich bitte korrigieren, wenn ich falsch liege): Nach dem Aufruf von poll()
bei * 1, wir ein anhängigen Versprechen schnell wieder bei * 2, so dass poll()
weiß warten. Dann nennen wir das Versprechen then()
Funktion bei * 3. Die Funktion p()
startet. Wenn fn()
(bekannt außerhalb p()
als waitIsOver()
) True bei * 4 zurückgibt, sind wir gut: Wir geben resolve()
und poll()
um * 1 erhält das abgelegte Versprechen, das es sucht.
Dann wird das Schlimme: Wenn fn()
false zurück an * 4 und wir sind innerhalb endTime
bei * 5 (was wahrscheinlich ist, das erste Gespräch unwahrscheinlich ist, nach endTime
auftreten), verwenden wir setTimeout()
an * 6 JS fragen eine Notiz im Stapel zu machen, um eine weitere p()
nach interval
Zeit instanziieren. Danach endet die erste Instanz von p()
bei * 7. An * 8, then()
weiß, dass p()
beendet wurde, ohne etwas zurückzugeben und interpretiert die Bedingung als false
und reject()
zurückgeben; Mit reject()
ist das Versprechen erledigt und kann sich nie ändern. Nach Ablauf von interval
wird jedoch eine Nachfolgerinstanz von p()
ausgelöst. Alles, was es zurückgibt, ist verloren; Das Versprechen ist erfüllt und then()
wurde beendet, nachdem die Ausführung auf einem unerwünschten Pfad gesendet wurde.
How do I convert an existing callback API to promises? empfiehlt einen Ansatz mit einem Konstruktor Versprechen, resolve()
callback()
Aufruf und reject()
errback
aufrufen. Ich habe versucht, die Technik, aber ich stieß auf das gleiche Problem der then()
Funktion endet, bevor ich es will. Ich habe noch nicht herausgefunden, wie man then()
als Patient in Wartestellung als Callback-Funktion macht.
Das setzt die Frage auf.Wieder:
Frage: Wie am besten helfen, die Funktion bleiben für spätere Rückgaben von resolve()
oder reject()
?
Dies ist, was wie eine übermäßig komplizierte Frage aussieht. Können Sie nur zwei Absätze nehmen und beschreiben, was Sie ohne Rücksicht auf Ihre aktuelle (und fehlerhafte) Anstrengung erreichen wollen. Ich denke, eine Lösung ist viel einfacher, als du es machst, aber dein Code ist so kompliziert, dass ich den Wald nicht von den Bäumen sehen kann, um genau zu verstehen, was du zu erreichen versuchst. – jfriend00
Ich hoffe auch, Sie wissen, dass Versprechen One-Shot-Geräte sind.Sie geben genau einmal einen Wert oder einen Fehler zurück, so dass sie nicht selbst für die Abfrageergebnisse arbeiten. Sie können in Umfragen verwendet werden, aber nicht für sich selbst. – jfriend00
Ich versuche eine 'poll()' Funktion mit nativen Versprechungen zu schreiben; Ich werde den Titel bearbeiten. Vielleicht besteht ein Teil der Motivation darin, mehr über einheimische Versprechen zu erfahren. Ich verstehe den One-Shot-Charakter von Versprechen. Haben Sie ein Beispiel für etwas, das ich verwenden kann, um ".then()" während einer Umfragezeit offen zu halten? – BaldEagle