Javascript 使用承诺或生成器函数等待DOM中的元素
我试图实现的是在检查元素当前是否在DOM中时能够使用承诺。我的想法是不使用Javascript 使用承诺或生成器函数等待DOM中的元素,javascript,ecmascript-6,promise,Javascript,Ecmascript 6,Promise,我试图实现的是在检查元素当前是否在DOM中时能够使用承诺。我的想法是不使用setTimeOut,而是真正使用窗口。requestAnimationFrame与setTimeOut完全相同,只是性能稍高一点 const doCheck = function(selector){ if (document.querySelector(selector) === null) { window.requestAnimationFrame(function () {
setTimeOut
,而是真正使用窗口。requestAnimationFrame
与setTimeOut
完全相同,只是性能稍高一点
const doCheck = function(selector){
if (document.querySelector(selector) === null) {
window.requestAnimationFrame(function () {
doCheck(selector);
});
} else {
return true;
}
};
export default function checkElement(selector) {
return new Promise(res => {
doCheck(selector);
res(true);
})
}
但是这当然不行,主要的问题是当选择器不存在时调用另一个函数,我如何用承诺来封装它?似乎您无法执行类似操作。您可以发送解析函数,并在完成后调用它
const-doCheck=函数(选择器,解析){
if(document.querySelector(选择器)==null){
window.requestAnimationFrame(函数(){
多切克(选择器,解析);
});
}否则{
决心(正确);
}
};
导出默认函数checkElement(选择器){
返回新承诺(res=>{
多切克(选择器,res);
})
}
因此,在上面的第一行中,您开始轮询元素
然后你立即解决承诺
那不行
只有在找到元素后,才需要解析承诺
i、 e.在这一行:
您的
doCheck
函数是异步的,但既不接受回调也不返回承诺。checkElement
中的承诺立即得到解决
@Amit的回答说明了如何传递回调(并使用它而不是返回
),下面是如何正确地使用承诺:
function rafAsync() {
return new Promise(resolve => {
requestAnimationFrame(resolve);
});
}
export default function checkElement(selector) {
if (document.querySelector(selector) === null) {
return rafAsync().then(() => checkElement(selector));
} else {
return Promise.resolve(true);
}
}
既然您讨论的是生成器函数,我假设您想要使用async
/wait
。您可以递归地执行此操作:
export default async function checkElement(selector) {
if (document.querySelector(selector) === null) {
await rafAsync();
return checkElement(selector);
} else {
return true;
}
}
或迭代:
export default async function checkElement(selector) {
while (document.querySelector(selector) === null) {
await rafAsync()
}
return true;
}
为什么要从DOM中获取这些信息?将元素添加到DOM的代码应该为您提供这一承诺。除了@Bergi的评论外,为什么您需要加载
raf
这样的轮询工作,例如每秒创建60个承诺等。您可以使用这两种方法中的任何一种,这似乎是在DOM发生变化时采取行动的正确方法。(比如当一个节点被附加到一个父节点上时等等)或者,但我认为突变事件有性能问题,并且为了突变观察者的利益而贬值。。。我跑进了一个兔子洞,我一辈子都做不出任何事情,哈哈,谢谢你:D
export default async function checkElement(selector) {
if (document.querySelector(selector) === null) {
await rafAsync();
return checkElement(selector);
} else {
return true;
}
}
export default async function checkElement(selector) {
while (document.querySelector(selector) === null) {
await rafAsync()
}
return true;
}