You could return or await a new Promise inside your async function and call its resolver in the event handler, but the thing with most events (and animationend is part of it) is that they may never fire, so you could be awaiting for something that will never happen.
In this particular case of an animationend, you can solve this issue thanks to the Web-Animations API which exposes a finished Promise that will either resolve or reject if the animation got stopped before its expected end:
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>