如何返回等待document对象isLoaded属性为true的Promise?
解决方案
我们可以通过两种方式实现等待document.isLoaded变为true的Promise,并在满足条件时执行指定逻辑X:
方式1:轮询检查(通用兼容方案)
这是最稳妥的方式,不管isLoaded由谁设置,都能准确监听状态变化:
function waitForDocumentLoaded() { return new Promise((resolve) => { // 先检查当前状态,已加载则直接完成 if (document.isLoaded) { resolve(); return; } // 定时轮询检查状态 const checkTimer = setInterval(() => { if (document.isLoaded) { clearInterval(checkTimer); resolve(); } }, 50); // 可根据需求调整轮询间隔,默认50ms }); } // 使用示例: waitForDocumentLoaded().then(() => { // 这里执行逻辑X console.log("触发X操作"); });
方式2:Proxy监听属性变化(高效无轮询)
如果document.isLoaded是由你的代码控制赋值的,可以用Proxy直接监听属性变更,避免轮询的性能开销:
// 保存原始document引用 const originalDoc = document; // 用Proxy包装document,监听isLoaded赋值 document = new Proxy(originalDoc, { set(target, prop, value) { const success = Reflect.set(target, prop, value); // 当isLoaded被设为true时,触发Promise完成 if (prop === 'isLoaded' && value === true) { window.__docLoadedResolver?.(); delete window.__docLoadedResolver; } return success; } }); function waitForDocumentLoaded() { return new Promise((resolve) => { if (document.isLoaded) { resolve(); return; } // 暂存resolve函数,等待属性变更触发 window.__docLoadedResolver = resolve; }); } // 使用示例: waitForDocumentLoaded().then(() => { // 执行逻辑X console.log("触发X操作"); });
注意事项
- 轮询间隔可按需调整:间隔越小响应越快,但会增加微小性能开销;间隔越大性能开销越低,响应会稍有延迟。
- Proxy方式要求所有修改
isLoaded的操作都通过包装后的document对象进行,否则无法触发监听。
内容的提问来源于stack exchange,提问作者Rue Vitale
相关产品推荐
相关产品推荐

