Skip to content Skip to sidebar Skip to footer

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"