简体   繁体   English

等待嵌套的...循环

[英]await in nested for … of loop

  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
  }

TournamentScraper returns an array of objects, which typically looks like this: TournamentScraper返回一个对象数组,通常如下所示:

{name: 'Foo', href: 'www.example.org/tournaments/foo/'}

The link points to the tournament's last season's first page. 该链接指向锦标赛上一季的第一页。 This page contains the links to the other seasons and a paginator (if any). 此页面包含指向其他季节和分页符(如果有)的链接。

MatchScraper's run returns some data, and sets the instance's dom property. MatchScraper的运行返回一些数据,并设置实例的dom属性。 getPages() and getSeasons() consumes this property and each returns an array of links. getPages()getSeasons()此属性,每个属性都返回一个链接数组。

The problem that results contains only the first batch of matches. 结果的问题仅包含第一批匹配。 I can see the 2nd page's matches in the console log, but they are not in the results array when traverse returns. 我可以在控制台日志中看到第二页的匹配,但是当traverse返回时它们不在结果数组中。

I found this rule which is against await in for loop. 我发现这条规则反对等待for循环。 The problem, that I have to wait for ms.run(href) , because it sets dom, and getPages() and getSeasons() needs it to be set, to extract the needed links. 问题是,我必须等待ms.run(href) ,因为它设置了dom,而getPages()getSeasons()需要设置它,以提取所需的链接。

I think this should work. 我认为这应该有效。 It utilizes Promise all rather than for loops 它利用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;
  }, []);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM