Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用承诺或生成器函数等待DOM中的元素_Javascript_Ecmascript 6_Promise - Fatal编程技术网

Javascript 使用承诺或生成器函数等待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 () {

我试图实现的是在检查元素当前是否在DOM中时能够使用承诺。我的想法是不使用
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;
}