Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: JavaScript puppeteer odotuttaminen

miniDisc [01.11.2019 18:23:55]

#

const puppeteer = require('puppeteer');
const fs = require('fs');

let urlList = [
    'www.esimerkki.fi/1',
    'www.esimerkki.fi/2',
    'www.esimerkki.fi/3',
    'www.esimerkki.fi/4',
    'www.esimerkki.fi/5',
    ...
    'www.esimerkki.fi/50',
]
let tulos = [{}]

for (var i = 0; i < urlList.length; i++) {
    let url = urlList[i];
    // puppeteer koodi:
    (async () => {
        const browser = await puppeteer.launch({ headless: true });
        const page = await browser.newPage();
        await page.goto(url, { waitUntil: 'networkidle2' });
        let Data = await page.evaluate(() => {
            // hakuasetukset...
        })
        tulos.push(Data)
        await browser.close()
    })()
}
fs.writeFile("./db.json", JSON.stringify(tulos))...

Elikkäs yritän hakea tietoa useammalta sivulta, mutta ongelmaksi muodostuu liian usean puppeteerin virtuaaliselaimen aukeaminen ja ohjelma hajoaa (puppeteerkin oletuksena rajoittaa nuo yhteentoista). Tai tuo fs.writeFile suoritetaan liian aikaisin. urlListan osiin jakamalla ja settimeoutilla olen saanut tuon toimimaan, mutta osaisiko joku neuvoa tähän oikean tavan, joka odottaa edellisen tehtävän valmistumista jonka jälkeen jatkaa seuraavaan?

kalppi [01.11.2019 20:38:31]

#

Siihen pitäisi käyttää promiseja. Eli niitä käytetään kutakuinkin seuraavasti:

const ps = [];

for(let i = 0; i < x; i++) {
   ps.push(new Promise((resolve, reject) => {
      resolve("tulos" + i);
   }));
}

console.log(await Promise.all(ps));

The Alchemist [02.11.2019 11:13:33]

#

No Promisejahan tuossa koko ajan käytetään. Ongelmana on se, että nykyisellään silmukka ei odota edellisen kierroksen tuloksen valmistumista. Koko silmukka ja sitä seuraava muu koodi täytyy siirtää koodissa olevan async-funktion sisälle, jolloin silmukan sisällä oleva await-käsky pysäyttää silmukan suorittamisen, kunnes awaitin kohteena oleva Promise valmistuu.

(async function () {
  for (...) {
    let result = await doWork()
  }
})()

miniDisc [02.11.2019 16:48:22]

#

The Alchemist kirjoitti:

(02.11.2019 11:13:33): No Promisejahan tuossa koko ajan käytetään...

No tämähän se. Kiitoksia!

The Alchemist [02.11.2019 17:57:06]

#

Täytyy vielä huomioida se, että koodi on hämmentävä yhdistelmä legacyä ja modernimpaa js:ää. Ei ole mitään järkeä sotkea var-avainsanalla luotuja muuttujia moderniin koodiin. Samoin vanhakantainen for-silmukka ja indeksimuuttujan käyttö kannattaisi korvata for-of-silmukalla. Samoin tuo, että jossain kohtaa on puolipisteistä ja toisaalla ei.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta