我正在制作一个弹出式div,我想对动画附加一个承诺,这样我就可以在弹出窗口结束后做点什么。
我的方法不起作用,因为我找不到将promise传递给事件处理程序上的函数的方法。似乎你不能在这里使用bind。我已经尝试过,虽然我可以解决这个承诺,但我无法删除事件处理程序
这里有什么不同的解决方案?
if (operator === '>') {
condition = (value1 > value2);
}
答案 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>
如果需要,您可以使用 async
和 await
-
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。