DOM 异步函数内的事件回调
DOM event callback within async function
考虑这个功能
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
}
}
有没有办法处理这种情况,并且在事件侦听器回调时实际上有一个异步函数resolve/return?
使用承诺。在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>
您可以 return 或在您的异步函数中等待一个新的 Promise 并在事件处理程序中调用它的解析器,但是大多数事件(动画结束是其中的一部分)的问题是它们可能永远不会触发,所以您可能正在等待永远不会发生的事情。
在 animationend 的这种特殊情况下,由于 Web-Animations API which exposes a finished
如果动画在预期结束前停止,Promise 将解决或拒绝,您可以解决此问题:
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>
考虑这个功能
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
}
}
有没有办法处理这种情况,并且在事件侦听器回调时实际上有一个异步函数resolve/return?
使用承诺。在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>
您可以 return 或在您的异步函数中等待一个新的 Promise 并在事件处理程序中调用它的解析器,但是大多数事件(动画结束是其中的一部分)的问题是它们可能永远不会触发,所以您可能正在等待永远不会发生的事情。
在 animationend 的这种特殊情况下,由于 Web-Animations API which exposes a finished
如果动画在预期结束前停止,Promise 将解决或拒绝,您可以解决此问题:
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>