【问题标题】:Axios inside a for loop not working using promises, only returning last resultfor循环中的Axios不能使用promise,只返回最后一个结果
【发布时间】:2023-04-09 22:02:01
【问题描述】:

我正在尝试在 for 循环中发出 axios POST 请求。但是,axios post POST 请求正在运行 n 次,只有循环的最后一个值。以 sheetName="Virudhunagar Beds" 的值运行两次。下面是我的一段代码:

const axios = require('axios')
const sheetDistrictMap = {
  "Ariyalur Beds": "5ea0abd3d43ec2250a483a4f", "Virudhunagar Beds": "5ea0abd3d43ec2250a483a58"
}
let promises = [];

for (sheetName in sheetDistrictMap) {
  promises.push(
    axios.post('https://tncovidbeds.tnega.org/api/hospitals', {
      District: sheetDistrictMap[sheetName],
      FacilityTypes: ["CHO", "CHC", "CCC"],
      IsGovernmentHospital: true,
      IsPrivateHospital: true,
      pageLimit: 100
    })
      .then(res => {
        var outputJsonArray = [];
        for (i = 0; i < res.data.result.length; i++) {
          var rowJson = {};
          var rowdata = res.data.result[i];
          rowJson["Name"] = rowdata["Name"];
          outputJsonArray.push(rowJson);
        }
        console.log("Parsed sheet: " + sheetName);
        console.log(outputJsonArray);
        console.log("========================================================");
      })
      .catch(error => {
        console.error(error)
      })
  )
}
Promise.all(promises).then(() => console.log("All data scraped"));

如何使用每个循环参数进行异步调用?

【问题讨论】:

  • 这是一个article,关于 javascript 循环中的变量范围和闭包
  • 太棒了。我没有考虑变量范围。我一直认为它是由非异步请求引起的。甚至不需要承诺。谢谢!

标签: javascript node.js asynchronous async-await axios


【解决方案1】:

您遇到了循环内的闭包问题。您可以使用let 和const 关键字来声明sheetName 变量。循环中的每次迭代都会有一个新变量sheetName 具有循环范围。

for (let sheetName in sheetDistrictMap) {
  // the rest code
}

欲了解更多信息,请参阅JavaScript closure inside loops – simple practical example

【讨论】:

    【解决方案2】:

    尝试将const 添加到sheetName 变量中。问题是没有它的变量的行为就像var 在大多数情况下是全局的。添加const 使变量具有块作用域,这样每次迭代都会有一个唯一的变量,而不是使用分配给sheetName 的最后一个值。

    for (const sheetName of Object.keys(sheetDistrictMap)) {
      promises.push(
        axios.post('https://tncovidbeds.tnega.org/api/hospitals', {
          District: sheetDistrictMap[sheetName],
          FacilityTypes: ["CHO", "CHC", "CCC"],
          IsGovernmentHospital: true,
          IsPrivateHospital: true,
          pageLimit: 100
        })
          .then(res => {
            var outputJsonArray = [];
            for (i = 0; i < res.data.result.length; i++) {
              var rowJson = {};
              var rowdata = res.data.result[i];
              rowJson["Name"] = rowdata["Name"];
              outputJsonArray.push(rowJson);
            }
            console.log("Parsed sheet: " + sheetName);
            console.log(outputJsonArray);
            console.log("========================================================");
          })
          .catch(error => {
            console.error(error)
          })
      )
    }
    

    【讨论】:

      【解决方案3】:

      我认为这里有两件事:

      1. let 或 const 在为变量创建全局范围的 for 循环中

      2. 您如何从 Promise 中获取数据。将其推送到数组后,您不需要.then,而是这样做:

      const axios = require('axios')
      const sheetDistrictMap = {
        "Ariyalur Beds": "5ea0abd3d43ec2250a483a4f", "Virudhunagar Beds": "5ea0abd3d43ec2250a483a58"
      }
      let promises = [];
      
      for (let sheetName in sheetDistrictMap) {
        promises.push(
          axios.post('https://tncovidbeds.tnega.org/api/hospitals', {
            District: sheetDistrictMap[sheetName],
            FacilityTypes: ["CHO", "CHC", "CCC"],
            IsGovernmentHospital: true,
            IsPrivateHospital: true,
            pageLimit: 100
          })
            
        )
      }
      Promise.all(promises).then((data) => 
         //data will array and in same sequence you hit the api
       // do the below processing for every response
         var outputJsonArray = [];
              for (i = 0; i < res.data.result.length; i++) {
                var rowJson = {};
                var rowdata = res.data.result[i];
                rowJson["Name"] = rowdata["Name"];
                outputJsonArray.push(rowJson);
              }
              //console.log("Parsed sheet: " + sheetName); // make sure you get the sheetName 
              console.log(outputJsonArray);
              console.log("========================================================");
            })
            .catch(error => {
              console.error(error)
            })
      

      【讨论】:

      • 只使用let 修复了它,甚至不需要承诺,所以我删除了它。谢谢兄弟!
      猜你喜欢
      • 2018-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-27
      • 1970-01-01
      • 1970-01-01
      • 2019-03-25
      相关资源
      最近更新 更多