typescript - jsdom怎么 "poll for the presence of a specific element."?

标签 typescript jsdom

在 jsdom 文档中 https://github.com/jsdom/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 选择器方法有问题。那么,是什么导致了这种无限循环,和/或是否有更好的方法来轮询元素?

最佳答案

这里有一些误解:

  1. elementOnPage(querySelector(...)) 的调用会执行一次(除非该代码本身位于某个循环或事件处理程序中)。如果执行时 DOM 元素存在,它将立即返回,否则它将永远不会再次执行选择器,因此您的函数将以 null 作为给定的参数无限运行。

    <
  2. 在 JavaScript 中,像 while 这样的循环是阻塞的(不包括这里不相关的工作线程),所以你基本上锁定了线程。即使您从循环内部重新运行querySelector,也会导致无限循环。

要执行轮询而不阻止 JS 执行,您需要使用 setIntervalsetTimeout .

此外,可等待函数应该返回一个Promise(从技术上讲,您可以await任何内容,但 Promise 是让它发挥作用的手段)。

这是一个未经测试的示例:

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");

关于typescript - jsdom怎么 "poll for the presence of a specific element."?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55801515/

相关文章:

javascript - jsdom的用例有哪些

node.js - 如何在 Nodejs 中使用 Observable Plot?

node.js - 如何使用 Puppeteer 和 JSDOM 下载 HTML、CSS 和 IMG

javascript - 带有 angular2 和 grunt 错误 TS2304 : Cannot find name 的 typescript

javascript - 将过时的JavaScript库与更新的TypeScript集成

angular - 属性 'replaceAll' 在类型 'string' 上不存在

javascript - ionic 2 ion-datetime ISO格式问题

javascript - 在js文件中加载html文件

node.js - 如何从一个简单的 jsdom 函数返回一个值?

javascript - Typescript 使用 [' ' ] 语法访问动态属性