如何修改Promise递归+setTimeout代码实现DOM元素检测并触发then回调?
问题分析与修复方案
你的代码核心问题是当元素不存在时,函数没有返回Promise,导致第一次调用checkElement()得到的是undefined,自然无法触发.then()回调;同时递归调用的Promise没有传递到初始调用链中。
修复后的代码(基础版)
function checkElement() { console.log("Check Element..."); // 确保函数始终返回Promise return new Promise((resolve) => { const element = jQuery('#idOfElement'); if (element.length > 0) { resolve(element); // 可选:把找到的元素传递给回调 return; } // 元素不存在时,递归检查并传递resolve setTimeout(() => { checkElement().then(resolve); }, 2000); }); }
更简洁的写法
function checkElement() { console.log("Check Element..."); const element = jQuery('#idOfElement'); if (element.length > 0) { return Promise.resolve(element); } // 元素不存在时,返回新Promise并递归检查 return new Promise((resolve) => { setTimeout(() => { checkElement().then(resolve); }, 2000); }); }
调用示例
checkElement().then((element) => { console.log("Element Found", element); });
为什么这样修改?
- 始终返回Promise:不管元素是否存在,函数都会返回一个Promise实例,确保调用
.then()时有合法的对象绑定回调。 - 连贯的Promise链:递归调用
checkElement()后,将其返回的Promise的resolve结果传递给当前Promise的resolve,保证当元素最终被找到时,初始调用的Promise会被触发,执行.then()中的逻辑。
可选:添加超时限制(避免无限轮询)
如果需要防止无限等待,可以增加最大尝试次数:
function checkElement(maxAttempts = 10) { console.log("Check Element..."); const element = jQuery('#idOfElement'); if (element.length > 0) { return Promise.resolve(element); } if (maxAttempts <= 0) { return Promise.reject(new Error("元素超过最大尝试次数仍未找到")); } return new Promise((resolve, reject) => { setTimeout(() => { checkElement(maxAttempts - 1).then(resolve).catch(reject); }, 2000); }); } // 调用时处理成功/失败 checkElement() .then((element) => console.log("Element Found", element)) .catch((err) => console.error(err.message));
内容的提问来源于stack exchange,提问作者fciri
相关产品推荐
相关产品推荐

