简体   繁体   English

仅在来自 axios 的请求的循环完成后执行代码块

[英]Execute block of code only after loop with requests from axios is finished

I have a script that reads an excel file and gets data from a specific column to perform a search on the Google Maps API where I use axios.我有一个脚本,它读取 excel 文件并从特定列获取数据以在 Google 地图 API 上执行搜索,其中我使用 axios。 For each request made, I need to save it in the newFileList variable.对于每个请求,我需要将其保存在newFileList变量中。 After completing all the requests, I must save the contents of this variable in a file.完成所有请求后,我必须将此变量的内容保存在文件中。 However, whenever I run my code, the file is being saved without the content of the newFileList variable.但是,每当我运行我的代码时,文件都会被保存而没有newFileList变量的内容。 How do I wait for all requests to finish before being able to save the content in the file?在能够将内容保存在文件中之前,如何等待所有请求完成?

Note : the reading, writing and requesting data are working.注意:读取,写入和请求数据正在工作。 I just need the rescue to happen only after all the loop requests are finished.我只需要在所有循环请求完成后才能进行救援。 I tried to solve by placing the loop inside a promisse and at the end of the execution of this loop I used resolve .我试图通过将循环放在一个承诺中来解决,并且在这个循环的执行结束时我使用了resolve

const xlsx = require("node-xlsx");
const fs = require("fs");
const coordinate = require("./coordinate");

const resourcePath = `${__dirname}/resources`;
const contentFile = xlsx.parse(`${resourcePath}/file-2.xlsx`)[0].data;
const newFile = [[...contentFile, ...["Latitude", "Longitude"]]];

for (let i = 1; i < contentFile.length; i++) {
  const data = contentFile[i];
  const address = data[2];
  coordinate
    .loadCoordinates(address)
    .then((response) => {
      const { lat, lng } = response.data.results[0].geometry.location;
      newFile.push([...data, ...[lat.toString(), lng.toString()]]);
    })
    .catch((err) => {
      console.log(err);
    });
}

console.log(newFile);

//The code below should only be executed when the previous loop ends completely

var buffer = xlsx.build([{ name: "mySheetName", data: newFile }]); // Returns a buffer
fs.writeFile(`${resourcePath}/file-3.xlsx`, buffer, function (err) {
  if (err) {
    return console.log(err);
  }
  console.log("The file was saved!");
});

The coordinate file:坐标文件:

const axios = require("axios");

module.exports = {
  loadCoordinates(address) {
    const key = "abc";
    return axios
      .get(`https://maps.googleapis.com/maps/api/geocode/json`, {
        params: {
          address,
          key,
        },
      })
  },
};

Will using an async IIFE help?使用异步IIFE 会有帮助吗?

const xlsx = require("node-xlsx");
const fs = require("fs");
const coordinate = require("./coordinate");

const resourcePath = `${__dirname}/resources`;
const contentFile = xlsx.parse(`${resourcePath}/file-2.xlsx`)[0].data;
const newFile = [[...contentFile, ...["Latitude", "Longitude"]]];

(async() => {
    try{
        for (let i = 1; i < contentFile.length; i++) {
          const data = contentFile[i];
          const address = data[2];
          await coordinate
            .loadCoordinates(address)
            .then((response) => {
              const { lat, lng } = response.data.results[0].geometry.location;
              newFile.push([...data, ...[lat.toString(), lng.toString()]]);
            })
            .catch((err) => {
              console.log(err);
            });
        }

        console.log(newFile);

        //The code below should only be executed when the previous loop ends completely

        var buffer = xlsx.build([{ name: "mySheetName", data: newFile }]); // Returns a buffer
        fs.writeFile(`${resourcePath}/file-3.xlsx`, buffer, function (err) {
          if (err) {
            return console.log(err);
          }
          console.log("The file was saved!");
        });
    } catch(e) {
        console.log(e)
    }
})();

Do note that I added await before coordinate.loadCoordinates , in order to make sure the first axios request is finished before we proceed to the next one.请注意,我在coordinate.loadCoordinates之前添加了await ,以确保在我们继续下一个请求之前完成第一个 axios 请求。

You need to use Promise.all() to wait until all the promises are resolved.您需要使用Promise.all()等到所有承诺都得到解决。 After that execute the writeToFile part.之后执行 writeToFile 部分。 For more info on Promise.all() , you can refer https://www.javascripttutorial.net/es6/javascript-promise-all/有关Promise.all()的更多信息,您可以参考https://www.javascripttutorial.net/es6/javascript-promise-all/

const requestPromiseArray = [];

for (let i = 1; i < contentFile.length; i++) {
  const data = contentFile[i];
  const address = data[2];
  requestPromiseArray.push(coordinate
    .loadCoordinates(address))
}

Promise.all(requestPromiseaArray).then(results=>{
     // Handle "results" which contains the resolved values.
      // Implement logic to write them onto a file
    var buffer = xlsx.build([{ name: "mySheetName", data: results }]);
    fs.writeFile(`${resourcePath}/file-3.xlsx`, buffer, function (err) {
      if (err) {
         return console.log(err);
       }
     console.log("The file was saved!");
});
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM