求封装WaitUntilThen函数以实现等待条件满足后执行指定函数的方案
求封装WaitUntilThen函数以实现等待条件满足后执行指定函数的方案
嘿,这个需求确实很实用!你提到Stack Overflow上有不少JavaScript等待相关的问题,但很少有封装成你想要的WaitUntilThen这种便捷函数的,我来给你梳理一下实现方案,顺便纠正你示例里的一个小误区~
首先得说,你原来的调用写法有个关键问题:如果直接传$('#myid').css('display')=='none'这种表达式,它会在调用WaitUntilThen的瞬间就执行并返回结果,之后不管元素的状态怎么变化,这个结果都不会更新了。所以我们得把条件改成一个函数传入,这样每次检查的时候都能重新计算当前状态。
基础版实现
先给你一个最核心的版本,用浏览器的requestAnimationFrame来做轮询,它会和浏览器的重绘节奏同步,比setInterval性能更好,尤其适合检查DOM状态:
function WaitUntilThen(conditionFunc, callback) { // 先立即检查一次,如果条件已经满足,直接执行回调 if (conditionFunc()) { callback(); return; } // 定义轮询检查的函数 const checkCondition = () => { if (conditionFunc()) { callback(); // 条件满足,执行回调 } else { requestAnimationFrame(checkCondition); // 不满足,继续下一轮检查 } }; // 启动轮询 requestAnimationFrame(checkCondition); }
正确的调用方式
注意这里的条件要传一个函数,而不是直接写表达式,比如你原来的需求应该这么调用:
// 用箭头函数包裹条件和回调(普通函数也可以) WaitUntilThen( () => $('#myid').css('display') === 'none', () => PrintCalculations() );
这么写的好处是,每次轮询的时候都会执行() => $('#myid').css('display') === 'none'这个函数,拿到元素最新的display状态,而不是只用第一次的结果。
进阶版(带超时机制)
如果担心条件永远不满足导致无限轮询,可以给函数加个超时参数,超时后自动停止并提示:
function WaitUntilThen(conditionFunc, callback, timeout = 5000) { const startTimestamp = Date.now(); const checkCondition = () => { // 先检查是否超时 if (Date.now() - startTimestamp >= timeout) { console.warn('WaitUntilThen: 等待超时,未满足指定条件'); return; } if (conditionFunc()) { callback(); } else { requestAnimationFrame(checkCondition); } }; // 先做一次初始检查 if (conditionFunc()) { callback(); return; } requestAnimationFrame(checkCondition); }
这个版本默认超时时间是5秒,你也可以自己传第三个参数修改,比如WaitUntilThen(..., ..., 10000)就是10秒超时。
备注:内容来源于stack exchange,提问作者Cymro
相关产品推荐
相关产品推荐

