Home > Enterprise >  Calling an asynchronous function, main thread wont stop and then there is result with undefined
Calling an asynchronous function, main thread wont stop and then there is result with undefined

Time:12-28

I am trying to improve my skills with async, await. So I am trying to make an app that collects the prices of different flights in different periods and then it decides in which period the plane ticket is cheapest for personal use.

const puppeteerExtra = require("puppeteer-extra");
const pluginStealth = require("puppeteer-extra-plugin-stealth");
puppeteerExtra.use(pluginStealth());
const PCR = require("puppeteer-chromium-resolver");

const howLongStart = 7;
const howLongEnd = 8;

const fromDate = new Date("2023-07-15");
const toDate = new Date("2023-08-31");

const airport = "PDL";

let tickets = [];

for (let i = 0; i < howLongEnd - howLongStart; i  ) {
  let howLong = howLongStart   i;

  let tempFromDate = new Date("2023-07-15");
  let tempFromD = new Date("2023-07-15");
  let tempToDate = addDays(tempFromD, howLong);

  async function ticketFirstMethod() {
    const ticketFirst = await searchFlight(airport, tempFromDate, tempToDate);
    tickets.push(ticketFirst);
  }

  ticketFirstMethod();

  while (addDays(tempToDate, 1) <= toDate) {
    tempFromDate = addDays(tempFromDate, 1);
    tempToDate = addDays(tempToDate, 1);

    async function ticketMethod() {
      let ticket = await searchFlight(airport, tempFromDate, tempToDate);
      tickets.push(ticket);
    }

    ticketMethod();
  }
}

let lowestTicket;

let lowest = Number.POSITIVE_INFINITY;
let highest = Number.NEGATIVE_INFINITY;
let tmp;
for (let i = tickets.length - 1; i >= 0; i--) {
  tmp = tickets[i][0];
  if (tmp < lowest) {
    lowest = tmp;
    lowestTicket = tickets[i];
  }
  if (tmp > highest) highest = tmp;
}

console.log(lowestTicket);

function addDays(date, days) {
  date.setDate(date.getDate()   days);
  return date;
}

async function searchFlight(airport, tempFromDate, tempToDate) {
  const stats = await PCR();
  const browser = await puppeteerExtra.launch({
    executablePath: stats.executablePath,
    headless: false,
  });
  const page = await browser.newPage();
  await page.goto(
    "https://www.pelikan.cz/cs/letenky/T:1,P:4000E_0_0,CDF:PRGMUCFRATXLVIE,CDT:C"  
      airport  
      ",R:1,DD:"  
      tempFromDate.getFullYear  
      "_"  
      tempFromDate.getMonth  
      "_"  
      tempFromDate.getDay  
      ",DR:"  
      tempToDate.getFullYear  
      "_"  
      tempToDate.getMonth  
      "_"  
      tempToDate.getDay  
      "/",
    { waitUntil: "networkidle2", timeout: 0 }
  );
  const cheapestPrice = await page.waitForSelector(
    "#flight-10000 > div:nth-child(1) > flights-flight:nth-child(1) > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > div:nth-child(2) > div:nth-child(1) > div:nth-child(1) > div:nth-child(3)"
  );
  const price = await page.evaluate((el) => el.textContent, cheapestPrice);
  const priceOnly = price.replace(/\D/g, "");
  const ticket = [priceOnly, page.url()];
  await browser.close();
  return ticket;
}

I have tried to put here an example of the code.

Can anyone please help me?

EXPECTED

Firstly I choose a period from when to when it should be searching for the ticket. Then I call searchFlight with this period of time to search for the ticket. The main thread will wait for the function to be processed and then the ticket is pushed to tickets.

BEHAVIOUR

The main thread will not wait and it continous so there is undefined ticket pushed to tickets.

I was trying to use the then method on the line where I am calling searchFlight function. In then method I put tickets.push(ticket). But that didn't work.

I was trying to search for fix but because I dont understand await, async that much I could not fix my code.

CodePudding user response:

First off, remove the (async () => { .... }() wrapper. That's superfluous and getting in the way. The parent function is already async so the wrapper is not needed.

Then, searchFlight is async so you need to await its result where you are calling it. And, you'll need to make it's parent function async so you can use that await.

const ticket = await searchFlight(airport, tempFromDate, tempToDate);

Then, you have to actually return a result from inside of searchFlight. Right now, you have no return result at the top level of that function.

I would suggest you do that by not mixing await and .then(). Just use await like this:

async function searchFlight(airport, tempFromDate, tempToDate){

    const stats = await PCR();
    const browser = await puppeteerExtra.launch({
        executablePath: stats.executablePath,
        headless: false
    });
    const page = await browser.newPage()
    await page.goto("...", {waitUntil: "networkidle2", timeout: 0})
    const cheapestPrice = await page.waitForSelector('...');
    const price = await page.evaluate(el => el.textContent, cheapestPrice);
    const priceOnly = price.replace(/\D/g, "");
    const ticket = [priceOnly, page.url()];
    await browser.close()
    return ticket;
}

And, please eliminate any use of var. One should only be using const or let in modern Javascript.

  • Related