Resolving A Promise With Eventlistener
I am working on a popup div and I would like to have a promise attached to the animation so I can do something after the popup ended. My approach does not work because I could not
Solution 1:
You do not need to pass the promise to the event handler, you need to pass the resolve
callback:
functionEventListenerForPopUp(resolve) {
this.removeEventListener("animationend", EventListenerForPopUp );
resolve();
}
// [...]returnnewPromise(function(resolve, reject) {
this.Div.addEventListener("animationend", function() {
EventListenerForPopUp.call(this, resolve);
}, false);
This looks a bit ugly to me, maybe you can look at something like this:
var div = this.Div;
returnnewPromise(function (resolve) {
div.addEventListener("animationend", functionanimationendListener() {
div.removeEventListener("animationend", animationendListener);
//call any handler you want here, if neededresolve();
});
});
Solution 2:
Alternatively, we can create a reusable utility function as a means of creating a promise from any DOM event:
constcreatePromiseFromDomEvent = (eventTarget, eventName, run?) =>
newPromise((resolve, reject) => {
consthandleEvent = () => {
eventTarget.removeEventListener(eventName, handleEvent);
resolve();
};
eventTarget.addEventListener(eventName, handleEvent);
try {
if (run) run();
catch (err) {
reject(err);
}
});
Example usage (with an MSE source buffer):
await createPromiseFromDomEvent(
sourceBuffer,
'update',
() => sourceBuffer.remove(3, 10)
);
Depending on the situation, the run
parameter may be needed to provide custom code to trigger the async operation (as above), or omitted if we know the operation has already started.
Solution 3:
Another option is to abstract an externally controlled promise as a reusable function -
functionthread () {
let resolve, reject
const promise = newPromise((res, rej) => {
resolve = res
reject = rej
})
return [promise, resolve, reject]
}
functioncustomPrompt(form) {
const [prompt, resolve] = thread()
form.yes.addEventListener("click", _ =>resolve(true), {once: true})
form.no.addEventListener("click", _ =>resolve(false), {once: true})
return prompt
}
customPrompt(document.forms.myform)
.then(response =>console.log("response:", response))
<formid="myform"><inputtype="button"name="yes"value="yes" /><inputtype="button"name="no"value="no" /></form>
You can use async
and await
if you wanted -
asyncfunctionmain () {
const response = awaitcustomPrompt(document.forms.myform)
console.log("response:", response)
}
You could easily add a timeout by modifying customPrompt
-
functioncustomPrompt(form) {
const [prompt, resolve, reject] = thread()
form.yes.addEventListener("click", _ =>resolve(true), {once: true})
form.no.addEventListener("click", _ =>resolve(false), {once: true})
// timeout after 30 secondssetTimeout(reject, 30000, Error("no response"))
return prompt
}
For other creative uses of thread
, see this Q&A.
Post a Comment for "Resolving A Promise With Eventlistener"