Element.classList.add()能否异步执行?异步封装及实现方法咨询
关于异步添加元素类名的问题解答
1. 你写的操作不属于异步执行
你封装的ca虽然是async函数,但函数内部只调用了同步的elem.classList.add(),没有任何真正的异步任务(比如网络请求、定时器、Promise异步操作等)。这种情况下,async函数会立即返回一个已完成状态的Promise,await它和直接执行同步代码没有区别——整个for循环还是会同步逐个执行类名添加操作,不会让出线程,本质还是同步逻辑。
2. 实现异步添加类名的方法
如果想要让类名添加操作异步执行(即放到事件循环的后续任务中,不阻塞当前同步代码),可以把classList.add()放到异步任务容器里,比如:
方法一:用Promise包装(微任务)
const caAsync = async function(elem, clss) { // 把操作放到微任务队列,当前同步代码执行完后再执行 await Promise.resolve(); elem.classList.add(clss); }; // 调用时,循环里的每个添加操作会依次进入微任务队列 for(let i = 0; i < number; ++i){ caAsync(somediv[i],"classname"); }
方法二:用setTimeout(宏任务)
const caAsync = function(elem, clss) { // 放到宏任务队列,延迟执行(最小延迟约4ms) setTimeout(() => { elem.classList.add(clss); }, 0); }; // 调用后所有添加操作会在当前同步代码完成后批量执行 for(let i = 0; i < number; ++i){ caAsync(somediv[i],"classname"); }
方法三:用requestAnimationFrame(适合DOM操作的异步任务)
如果是和DOM渲染相关的类名添加,用这个更合适,它会在浏览器下一次重绘前执行:
const caAsync = function(elem, clss) { requestAnimationFrame(() => { elem.classList.add(clss); }); }; for(let i = 0; i < number; ++i){ caAsync(somediv[i],"classname"); }
内容的提问来源于stack exchange,提问作者Gurami Nikolaishvili
相关产品推荐
相关产品推荐

