异步函数内的DOM事件回调



考虑这个函数

async function Animate(element)
{
// do something with dom element's animation, triggering it

element.addEventListener("animationend", 
function(event)
{
// this is when Animate(element) should resolve/return
}
}

是否有任何方法来处理这种情况,并实际上有一个async函数解析/返回事件监听器回调?

使用承诺。在animationend事件监听器中解析它。

const animateThis = async(elem) => {
return new Promise(resolve => {
elem.classList.add("active");
elem.addEventListener('animationend', () => {
elem.classList.remove("active");
resolve();
});
});
};
(async function() {
const elem = document.querySelector(".animation");
console.log("before call");
await animateThis(elem);
console.log("after call");
}());
.animation.active {
animation-duration: 2s;
animation-name: slidein;
animation-iteration-count: 2;
}
@keyframes slidein {
from {
margin-left: 100%;
width: 300%;
}
to {
margin-left: 0%;
width: 100%;
}
}
<p class="animation">Hello World</p>

你可以在async函数中返回或等待一个新的Promise,并在事件处理程序中调用它的解析器,但是大多数事件(animationend是其中的一部分)可能永远不会触发,所以你可能在等待一些永远不会发生的事情。

在这个动画结束的特殊情况下,你可以解决这个问题,这要感谢Web-Animations API,它暴露了一个finished承诺,如果动画在预期结束之前停止,它将解决或拒绝:

const elem = document.querySelector(".animate");
(async () => {
// never gonna resolve
const prom = new Promise((resolve) => {
elem.addEventListener("animationend", () => resolve(), { once: true });
});
// await prom;
prom.then(()=>console.log("event fired"));
// using the Web Animation API
// we should do more filtering on the Animations here
// to be sure we get our own
const anim = elem.getAnimations()[0];
try {
await anim.finished;
}
catch(err) { }
console.log("anim ended");
})().catch(console.error);
// stop the animation before completion
setTimeout(() => elem.remove(), 2000);
.animate {
width: 50px;
height: 50px;
background: green;
animation: anim 10s linear;
}
@keyframes anim {
to {
transform: translate(120px,0);
}
}
<div class="animate"></div>

相关内容

  • 没有找到相关文章

最新更新