等到功能完成,然后呈现页面

Wait until function is complete and then render the page

我有一个抓取元素和 return 元素值的函数。这是reale-scraper.js的代码:

module.exports.RealeScraper = function() {

return new Promise((res, rej) => {

var url = 'example.com';
var compagnia;

//Start Puppeteer and scrape element
ptr.launch().then(async browser => {
    const page = await browser.newPage();
    await page.setViewport({ width: 1280, height: 800 });

    await page.goto(url, {waitUntil: "networkidle0"});

    await page.type('input[name="username"]', config.utente);
    await page.type('input[name="password"]', config.pass);

    await Promise.all([
        page.click('input[type="SUBMIT"]'),
        page.waitForNavigation({waitUntil: 'networkidle2'})
    ]);

    await page.waitForSelector('#tableSceltaProfilo > tbody > tr:nth-child(1) > td:nth-child(2)');

    const element = await page.$("#tableSceltaProfilo > tbody > tr:nth-child(1) > td:nth-child(2)");
    compagnia = await page.evaluate(element => element.textContent, element);

    await page.screenshot({path: 'screenshot.png'});

    await browser.close();
});

res(compagnia);
});
} 

然后我调用该函数并尝试将数据发送到我在 home.js:

中的 ejs 模板
var scraper = require('../scrapers/reale-scraper');
router.get('/home', function(req, res, next) {

 RealeScraper().then((compagnia) => {
     res.render('nuovo-sinistro', {
        titolo: 'Manager Perizie',
        compagnia: compagnia
     });
 }).catch((error) => {
     console.log(error);
 });
 });

我想等到 'RealeScraper' 完成并 return 给我一个值,以便我可以将它传递给 res.render。我试过使用 Promise 但它不起作用。它没有给我任何错误,但是当我加载页面时,该函数没有启动,因此在没有变量的情况下呈现。

我也尝试过不同的方法,但最终让页面永远加载。

非常感谢任何帮助,谢谢!

您同时调用//Start Puppeteer and scrape elementres(compagnia);,而compagnia为空,已返回

scrape element 完成后调用 res

...
await browser.close();
res(compagnia);
...

我认为如果你只使用 async\await 这样会更好:

module.exports.RealeScraper = async function () {
  var url = 'example.com';
  var compagnia;

  //Start Puppeteer and scrape element
  let browser = await ptr.launch();
  const page = await browser.newPage();
  await page.setViewport({ width: 1280, height: 800 });

  await page.goto(url, { waitUntil: "networkidle0" });

  await page.type('input[name="username"]', config.utente);
  await page.type('input[name="password"]', config.pass);

  await page.click('input[type="SUBMIT"]'); // why you do that in parallel?
  await page.waitForNavigation({ waitUntil: 'networkidle2' });

  await page.waitForSelector('#tableSceltaProfilo > tbody > tr:nth-child(1) > td:nth-child(2)');

  const element = await page.$("#tableSceltaProfilo > tbody > tr:nth-child(1) > td:nth-child(2)");
  compagnia = await page.evaluate(element => element.textContent, element);

  await page.screenshot({ path: 'screenshot.png' });

  await browser.close();

  return compagnia;
}



// ...
var scraper = require('../scrapers/reale-scraper');
router.get('/home', async function (req, res, next) {

  try {
    let compagnia = await RealeScraper();
    res.render('nuovo-sinistro', {
      titolo: 'Manager Perizie',
      compagnia: compagnia
    });
  } catch (error) {
    console.log(error);
  }
});