异步等待元素加载所以我可以用 jquery 找到它

async wait for element to load in so i can find it with jquery

我不是很懂异步。我有这样的功能:

function getTeam() {
    let sir = setInterval(() => {
        const teamsGrid = $('[class*="teamsgrid"]').find("p");
        const firstTeam = $(teamsGrid[0]).text();
        if (firstTeam != '') {
          clearInterval(sir)
          return firstTeam.trim()
        }
    }, 100)
}

我不是js高手。我只想在它加载时获取该元素,此代码在用户脚本中为 运行ning 并且 // @运行-at document-idle 也无济于事。我知道我将不得不进入异步 js 承诺回调和任何一天,但我真的不明白在文档页面和其他 Whosebug 之后它是如何工作的。 当我 console.log 这个函数它会打印一次 undefined 然后如果我有一个 console.log 里面如果它会打印实际的团队名称。 我要如何等待那个结果

function getTeam() {
    let sir = new Promise((res, rej) => {
    const teamsGrid = $('[class*="teamsgrid"]').find("p");
        const firstTeam = $(teamsGrid[0]).text();
        if (firstTeam != '') {
          clearInterval(sir);
          res(firstTeam.trim());
        }
    });
    return sir();
}

据我了解,您正在寻找 firstTeam。此外,我们假设始终存在 firstTeam,因此不存在没有团队名称的情况。 我不确定您在哪里提出需要时间从这段代码中诚实地处理的请求。到目前为止,同步功能看起来应该没问题。您是否正在联系 API?

关于 javascript 语言部分的答案,如果问题

可以 将您的代码修改为以下内容(但 不要 - 请参阅下文 - 我只是将其提供为你的 Whosebug 标签包括 async/await):

async function getTeam() {
    return new Promise(resolve => {
      const sir = setInterval(() => {
        const teamsGrid = $('[class*="teamsgrid"]').find("p");
        const firstTeam = $(teamsGrid[0]).text();
        if (firstTeam != '') {
          clearInterval(sir);
          resolve(firstTeam.trim());
        }
      }, 100);
    });
}

// ... and then anywhere else in your code:
doSomethingSynchronous();
const team = await getTeam();
soSomethingSynchronousWithTeam(team);

注意 这仅适用于支持 >= ECMAScript 2017 的现代浏览器: https://caniuse.com/async-functions(但幸运的是,现在最多!)

关于隐式“如何等待元素部分”的回答

...你真的不应该主动等待一个元素,因为这对 CPU 来说是不必要的繁重。通常,一旦创建了您正在等待的元素,就会有某种事件通知您。只需听一下,然后 运行 你的代码。

如果目前没有这样的事件怎么办:

  • 如果您可以控制 创建元素的代码,那么您自己触发一个(参见 https://api.jquery.com/trigger/ 示例)。
  • 如果元素由第三方库或其他您无法轻易修改的东西创建,您可以使用 MutationObserver (see this StackBlitz answer to a related question) 和 运行您的 getTeam 代码仅在某些内容发生变化时才执行,而不是每 100 毫秒执行一次(对性能的影响较小!)

如果你愿意,你可以让它异步,但主要部分我们将改为使用事件。有一个特殊的对象叫做变异观察者。只要您正在观察的元素发生变化,它就会调用您提供的函数。

查看突变观察者文档以了解以下代码:https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

虽然对你的 HTML 了解不多,但我只能说这应该有效:

function getTeam() {
  const teamsGrid = $('[class*="teamsgrid"]').find("p");
  const firstTeam = $(teamsGrid[0]).text();
  if (firstTeam != '') {
    return firstTeam.trim()
  }
}

function getTeamWhenAvailable() {
  // returning a promise allows you to do "await" and get result when it is available
  return new Promise((resolve, reject) => {
    // furst try if element is available right now
    const teamText = getTeam();
    if(teamText) {
      // resolve() "returns" the value to whoever is doing "await"
      resolve(teamText);
      // resolve does not terminate this function, we need to do that using return
      return;
    }
      

    // Mutation observer gives you list of stuff that changed, but we don't care, we just do our own thing
    const observer = new MutationObserver(()=>{
          const teamText = getTeam();
          if(teamText) {
            // stop observing
            observer.disconnect();
            // resolve the value
            resolve(teamText);
          }
    });
    observer.observe(document.body, { childList: true, subtree: true };
  })
}

// usage, the extra brackets around the lambda cause it to invoke immediatelly

(async () => {
  console.log("Waitinf for team...");
  const teamName = await getTeamWhenAvailable();
  console.log("Result team name: ", teamName)
})();

现在你可能想缩小变异观察者的范围,在上面的例子中它观察整个文档。试着去观察你可以信赖的最深的元素不会被移除。

如果你需要多次接收团队名称,我认为你应该只使用观察者而不是异步的东西。