使用EventListener解析一个promise

时间:2016-03-01 09:09:18

标签: javascript

我正在制作一个弹出式div,我想对动画附加一个承诺,这样我就可以在弹出窗口结束后做点什么。

我的方法不起作用,因为我找不到将promise传递给事件处理程序上的函数的方法。似乎你不能在这里使用bind。我已经尝试过,虽然我可以解决这个承诺,但我无法删除事件处理程序

这里有什么不同的解决方案?

if (operator === '>') {
    condition = (value1 > value2);
}

3 个答案:

答案 0 :(得分:13)

您无需将承诺传递给事件处理程序,您需要传递resolve回调:

function EventListenerForPopUp(resolve) {
            this.removeEventListener("animationend", EventListenerForPopUp );
            resolve();
}   

// [...]

        return new Promise(function(resolve, reject) {
            this.Div.addEventListener("animationend", function() {
                EventListenerForPopUp.call(this, resolve);
            }, false);

这看起来有点难看,也许你可以看看这样的东西:

var div = this.Div;
return new Promise(function (resolve) {
    div.addEventListener("animationend", function animationendListener() {
        div.removeEventListener("animationend", animationendListener);
        //call any handler you want here, if needed
        resolve();
    });
});

答案 1 :(得分:1)

或者,我们可以创建一个可重用的实用程序功能,作为从任何DOM事件创建承诺的一种方式:

const createPromiseFromDomEvent = (eventTarget, eventName, run?) =>
    new Promise(resolve => {
        const handleEvent = () => {
            eventTarget.removeEventListener(eventName, handleEvent);

            resolve();
        };

        eventTarget.addEventListener(eventName, handleEvent);

        if (run) run();
    });

用法示例(带有MSE源缓冲区)

await createPromiseFromDomEvent(
    sourceBuffer,
    'updatend',
    () => sourceBuffer.remove(3, 10)
);

根据情况,可能需要run参数来提供用于触发异步操作的自定义代码(如上所述),如果我们知道该操作已经开始,则可以省略。

答案 2 :(得分:0)

另一种选择是将外部控制的 promise 抽象为可重用的函数 -

function thread () {
  let resolve, reject
  const promise = new Promise((res, rej) => {
    resolve = res
    reject = rej
  })
  return [promise, resolve, reject]
}

function customPrompt(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))
<form id="myform">
  <input type="button" name="yes" value="yes" />
  <input type="button" name="no" value="no" />
</form>

如果需要,您可以使用 asyncawait -

async function main () {
  const response = await customPrompt(document.forms.myform)
  console.log("response:", response)
}

您可以通过修改 customPrompt -

轻松添加超时
function customPrompt(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 seconds
  setTimeout(reject, 30000, Error("no response"))
  return prompt
}

有关 thread 的其他创造性用途,请参阅 this Q&A