簡體   English   中英

調用異步 function,主線程不會停止,然后結果為 undefined

[英]Calling an asynchronous function, main thread wont stop and then there is result with undefined

我正在嘗試通過 async,await 提高我的技能。 所以我想做一個應用程序,收集不同時期不同航班的價格,然后它決定哪個時期的機票最便宜供個人使用。

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;
}

我試圖在這里放一個代碼示例。

誰能幫幫我嗎?

預期的

首先我選擇一個時間段,從什么時候到什么時候應該搜索票證。 然后我用這段時間調用 searchFlight 來搜索機票。 主線程會等待 function 處理完畢,然后將工單推送到工單。

行為

主線程不會等待並且它是連續的,所以有未定義的票被推送到票。

我試圖在我調用 searchFlight function 的行上使用then方法。在 then 方法中我放置了tickets.push(ticket) 但這沒有用。

我試圖搜索修復程序,但因為我不了解等待,異步那么多我無法修復我的代碼。

首先,刪除(async () => {.... }()包裝器。這是多余的並且妨礙了。父 function 已經是async的,因此不需要包裝器。

然后,searchFlight 是異步的,因此您需要在調用它的地方await其結果。 而且,您需要使其成為父級 function async ,以便您可以使用await

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

然后,您必須實際從 searchFlight 內部返回結果。 現在,您在 function 的頂層沒有返回結果。

我建議您不要混合使用await.then()來做到這一點。 像這樣使用await

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;
}

並且,請消除對var的任何使用。 在現代 Javascript 中應該只使用constlet

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM