【问题标题】:Javacript for loop wait for function to finish? [duplicate]Javascript for循环等待函数完成? [复制]
【发布时间】:2021-09-07 16:21:26
【问题描述】:

我正在制作一个包含三个不同功能的程序:

  1. downloadPDF:从网上下载 PDF
  2. getPDF: 读取并解析 pdf
  3. getData: 循环通过 getPDF

我遇到的问题是第三个函数 (getData) 有一个运行 getPDF 的 for of 循环,似乎在尝试 console.log getPDF 返回的结果之前它没有让 getPDF 完成.

下面是三个函数:

async function downloadPDF(pdfURL, outputFilename) {
  let pdfBuffer = await request.get({uri: pdfURL, encoding: null});
  console.log("Writing downloaded PDF file to " + outputFilename + "...");
  fs.writeFileSync(outputFilename, pdfBuffer);
}

async function getPDF(query, siteName, templateUrl, charToReplace) {
  const currentWeek = currentWeekNumber().toString();
  await downloadPDF(templateUrl.replace(charToReplace, currentWeek), "temp/pdf.pdf");
  var resultsArray = []
  let dataBuffer = fs.readFileSync("temp/pdf.pdf");
    pdf(dataBuffer).then(function(data) {
      pdfContent = data.text;
      const splittedArray = pdfContent.split("\n");
      const parsedArray = splittedArray.map((item, index) => {
          if(item.includes(query)) {
              resultsArray.push({result: item, caseId: splittedArray[index-1].split(',', 1)[0], site: siteName});
          }
        }).filter(value => value);
        return(resultsArray);
  });
  fs.unlinkSync("temp/pdf.pdf"); //deletes the downloaded file
}

async function getData(query, desiredSites) {
  var resultsArray = []
  for (const value of desiredSites) {
    let result = await getPDF(query, sitesList.sites[value].name, sitesList.sites[value].templateUrl, sitesList.sites[value].charToReplace);
    console.log(result)
  }
}
getData("test", ['a', 'b']);

在底部函数(getData)中,console.log 结果为undefined 我猜这与承诺有关。有任何想法吗?非常感谢!

【问题讨论】:

  • sitesList 来自哪里?
  • getPDF 中调用了一个名为pdf 的函数。这似乎是一个异步函数(特别是一个承诺),因为您调用了then。这个功能根本不需要等待。同样getPDF 似乎没有返回任何东西,所以result 将出现undefined
  • 对于投票关闭作为重复的人来说,这并不是真正的重复。异步循环不是问题——OP 已经完美地实现了这一点。问题出现在堆栈的更深处。我可能仍会投票关闭,但“不可复制或由拼写错误引起”,因为该决议不太可能对未来的读者有所帮助。
  • @Wing 我在 getPDF 的末尾做 return(resultsArray);
  • 返回值在传递给then的函数内部。它不会从getPDF 返回。请参阅How to return the response from an asynchronous call?Return from a promise then()

标签: javascript for-loop async-await promise


【解决方案1】:

getPDF 中,您应该使用await 而不是.then 链接所有异步函数,反之亦然。

您可以将 await 与 .then 混合使用,但将它们与线性代码链接起来并不容易。人们使用 await 的原因是他们想让代码看起来线性且易于维护。

async function downloadPDF(pdfURL, outputFilename) {
  let pdfBuffer = await request.get({ uri: pdfURL, encoding: null });
  console.log("Writing downloaded PDF file to " + outputFilename + "...");
  fs.writeFileSync(outputFilename, pdfBuffer);
}

async function getPDF(query, siteName, templateUrl, charToReplace) {
  const currentWeek = currentWeekNumber().toString();
  await downloadPDF(
    templateUrl.replace(charToReplace, currentWeek),
    "temp/pdf.pdf"
  );
  var resultsArray = [];
  let dataBuffer = fs.readFileSync("temp/pdf.pdf");
  const data = await pdf(dataBuffer);
  pdfContent = data.text;
  const splittedArray = pdfContent.split("\n");
  const resultsArray = splittedArray
    .filter(item => item.includes(query))
    .map(item => ({
      result: item,
      caseId: splittedArray[index - 1].split(",", 1)[0],
      site: siteName,
    }));

  fs.unlinkSync("temp/pdf.pdf"); //deletes the downloaded file
  return resultsArray;
}

async function getData(query, desiredSites) {
  for (const value of desiredSites) {
    let result = await getPDF(
      query,
      sitesList.sites[value].name,
      sitesList.sites[value].templateUrl,
      sitesList.sites[value].charToReplace
    );
    console.log(result);
  }
}

getData("test", ["a", "b"])
  .then(() => console.log("done"))
  .catch(console.log);

【讨论】:

    猜你喜欢
    • 2022-01-04
    • 1970-01-01
    • 2014-07-19
    • 2022-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    相关资源
    最近更新 更多