Typescript Jsdom如何;投票确定是否存在特定元素;?

Typescript Jsdom如何;投票确定是否存在特定元素;?,typescript,jsdom,Typescript,Jsdom,在jsdom文档中,在异步脚本加载下,建议轮询特定元素的存在,作为确保dom加载所需内容的方法 以下代码是我对此的解释: const elementOnPage = (arg: HTMLElement | null): HTMLElement => { let tried = arg; while (tried === null) { // debugger; console.log("nothing yet"); tried = arg; } re

在jsdom文档中,在异步脚本加载下,建议轮询特定元素的存在,作为确保dom加载所需内容的方法

以下代码是我对此的解释:

const elementOnPage = (arg: HTMLElement | null): HTMLElement => {
  let tried = arg;
  while (tried === null) {
    // debugger;
    console.log("nothing yet");
    tried = arg;
  }
  return tried;
};
然后调用函数,如下所示:

...
await elementOnPage(
        dom.window.document.querySelector("#some element that I know will eventually be loaded onto the page")
      );
...
尽管我知道这个元素最终会被加载,但这会导致一个无限循环。看起来这个参数可能第一次被计算为null,然后在以后的每一次都被设置为null,但我不确定。无论如何,我也试过使用

dom.window.document.getElementsByClassName("some class that will eventually have member elements")

并检查结果集合长度是否不是0,但这将返回相同的无限循环。我认为dom选择器方法不是问题所在。那么,是什么导致了这种无限循环,和/或是否有更好的方法来轮询元素?

这里有一些误解:

  • elementOnPage(querySelector(…)
    的调用执行一次(除非代码本身在某个循环或事件处理程序中)。如果DOM元素在执行时存在,它将立即返回,否则它将不再执行选择器,因此函数将以给定的参数
    null
    无休止地运行

  • 在JavaScript中,像
    while
    这样的循环是阻塞的(这里不包括无关的工作线程),因此基本上是锁定线程。即使从循环内部重新运行
    querySelector
    ,也会导致无限循环

  • 执行轮询而不阻止要使用或的JS执行

    另外,等待函数应该返回一个
    承诺
    (从技术上讲,您可以
    等待
    任何东西,但承诺是您使其有用的手段)

    以下是一个未经测试的示例:

    const elementOnPage = (query: string, timeout: number = 10000): Promise<HTMLElement | null> => {
      return new Promise((resolve, reject) => {
        const startTime = Date.now();
        const tryQuery = () => {
          const elem = dom.window.document.querySelector(query);
          if (elem) resolve(elem); // Found the element
          else if (Date.now() - startTime > timeout) resolve(null); // Give up eventually
          else setTimeout(tryQuery, 10); // check again every 10ms
        }
        tryQuery(); // Initial check
      });
    };
    
    
    // Elsewhere:
    const elem = await elementOnPage("#some_element");
    
    const-elementOnPage=(查询:字符串,超时:number=10000):Promise=>{
    返回新承诺((解决、拒绝)=>{
    const startTime=Date.now();
    const tryQuery=()=>{
    const elem=dom.window.document.querySelector(查询);
    if(elem)resolve(elem);//找到元素
    如果(Date.now()-startTime>timeout)解析(null);//最终放弃
    else setTimeout(tryQuery,10);//每10毫秒检查一次
    }
    tryQuery();//初始检查
    });
    };
    //其他地方:
    const elem=wait elementOnPage(“#某些#u元素”);
    
    我明白了。这很有意义,因为我试图传递一个承诺,返回queryselector而不是选择器本身,但它似乎仍然返回一个无限循环。那么我如何确定要使用的间隔呢?只是随意的?假设我使用了2秒的间隔。这应该足够长,页面上的脚本可以加载,但如果连接速度非常慢,则不会加载。我添加了一个示例。您可以将检查间隔设置得非常小,比如每10毫秒甚至1毫秒检查一次(尽管实际执行不会那么精确)。只要你在一段时间内完成。