在嵌套的 for ... of 循环中等待

use*_*719 5 javascript async-await

  async traverse(url) {
    const ts = new TournamentScraper()
    const ms = new MatchScraper()
    const results = []
    const tournaments = await ts.run(url)
    for(let href of tournaments.map(t => t.href)){
      let matches = await ms.run(href)
      let pages = ms.getPages()
      let seasons = ms.getSeasons()
      //console.log(pages)
      //console.log(seasons)
      results.push(matches)
      for(let href of pages) {
        //console.log(href)
        matches = await ms.run(href)
        //console.log(matches)
        results.push(matches)
      }
    }

    return results
  }
Run Code Online (Sandbox Code Playgroud)

TournamentScraper 返回一个对象数组,通常如下所示:

{name: 'Foo', href: 'www.example.org/tournaments/foo/'}
Run Code Online (Sandbox Code Playgroud)

该链接指向锦标赛上赛季的首页。此页面包含其他季节的链接和分页器(如果有)。

MatchScraper 的运行返回一些数据,并设置实例的 dom 属性。getPages()getSeasons()使用此属性,每个属性都返回一个链接数组。

结果的问题仅包含第一批匹配项。我可以在控制台日志中看到第二页的匹配项,但返回时它们不在结果数组中traverse

我发现这条规则反对 for 循环中的等待。问题是,我必须等待ms.run(href),因为它设置了 dom,并且getPages()需要getSeasons()设置它,以提取所需的链接。

piz*_*r0b 2

我认为这应该有效。它使用 Promise all 而不是 for 循环

const run = href => ms.run(href);

async function getMatches(href) {  
  const out = [];
  const matches = await run(href);
  const pages = ms.getPages();

  out.push(matches);

  if(pages.length) {
    const pageResults = await Promise.all(pages.map(href => run(href)));
    out.push(...pageResults);
  }

  return out;
}

async function traverse(url) {
  const ts = new TournamentScraper();
  const ms = new MatchScraper();
  const tournaments = await ts.run(url)
  const matches = await Promise.all(tournaments.map(t => getMatches(t.href)));
  return matches.reduce((a, b) => { 
    a.push(...b);
    return a;
  }, []);
}
Run Code Online (Sandbox Code Playgroud)