【问题标题】:How do I use an Axios response as a parameter in a for loop?如何在 for 循环中使用 Axios 响应作为参数?
【发布时间】:2019-06-12 02:36:58
【问题描述】:

我正在编写一个从 API 检索数据的脚本。我需要在 API 中获取所有数据实例,但 API 一次将我限制为 250 个结果。响应还给了我一个偏移量,我可以在新的 API 调用中使用它来获取下一组结果。我知道我需要对 API 进行多少次调用,我的想法是在 params 中使用一个变量,以便在每次调用 API 后更新偏移量。问题总是回到实际设置变量并在循环再次运行时使用它。

我能够运行 ajax 请求并返回数据,然后将偏移量设置为变量。我尝试创建一个初始 API 调用,然后返回响应,然后在 for 循环内的新函数中使用该返回值。这似乎是最接近我的解决方案,但每次循环运行时,变量都会重置为 null,并且我会返回初始偏移值。

这是最新的代码:

for (iteration = 1; iteration < 4; iteration++) {
  let offsetValue;
  pullWriteData = offsetValue => {
    return axios({
      method: "get",
      url: "https://api.hubapi.com/engagements/v1/engagements/paged",
      params: {
        hapikey: "API_KEY_HERE",
        limit: 250,
        offset: offsetValue
      }
    }).then(response => {
      return response.data;
    });
  };

  pullWriteData().then(data => {
    offsetValue = data.offset;
    console.log("New offset value: " + offsetValue);
    return offsetValue;
  });
}

此代码返回:

New offset value: 12345678
New offset value: 12345678
New offset value: 12345678

我还在我的 pullWriteData() 调用的 .then 中构建了第二个 Axios 调用,这确实有效,但这肯定违背了为我编写程序的目的。

我的期望是这将运行初始 API 调用,将数据写入文件,更新 offsetValue,使用新的 offsetValue 再次运行 API 调用,将响应写入文件,更新 @ 987654326@ 并重复,直到我提取所有数据。

就将数据写入文件而言,我已经能够使用fs 来做到这一点。它只是让offsetValue 值更新,这似乎让我很烦恼。

提前感谢您的任何指导。

【问题讨论】:

    标签: javascript for-loop promise axios


    【解决方案1】:

    使用async/await,您可以使用promises 执行以下操作,以确保您每次都获得下一个offset 并将其设置在循环中,以便下一个链接的async 请求传递新的offset到请求。

    注意:在您当前的迭代中,您只会发出 3 个请求,从 GET 请求中没有 offset= 开始,然后接下来的 2 个请求将使用返回的 @987654328 @ 值分别来自第一个和第二个请求,第三个返回的offset 值没有被使用,因为没有发出另一个请求。

    const getEngagements = (offsetValue) => {
      return new Promise((resolve, reject) => {
        axios({
          method: "get",
          url: "https://api.hubapi.com/engagements/v1/engagements/paged",
          params: {
            hapikey: "demo",
            limit: 250,
            offset: offsetValue
          }
        }).then(response => {
          return resolve(response.data);
        }).catch(error => {
          return reject(error.message)
        })
      })
    }
    
    const startPaging = async() => {
      let offsetValue;
      for (let num of [1, 2, 3]) {
        await getEngagements(offsetValue).then((data) => {
          offsetValue = data.offset;
          console.log("New offset value: " + offsetValue);
        })
      }
    
      /* You could also do a while() loop for while 
       * dataHasMore = true from response data, if you
       * weren't doing a fixed iteration..
       */
    
      /*
      let dataHasMore = true;
      while (dataHasMore) {
       await getEngagements(offsetValue).then((data) => {
          dataHasMore = data.hasMore;
          offsetValue = data.offset;
          console.log("New offset value: " + offsetValue);
        })
      }
      */
    
      console.log('Done');
    }
    
    startPaging();
    &lt;script src="https://unpkg.com/axios/dist/axios.min.js"&gt;&lt;/script&gt;

    【讨论】:

    • 这与我曾经拥有的非常接近。如此接近,以至于我不太确定以前走这条路线时缺少什么。我想我没有在正确的地方设置 offsetValue。我也非常感谢您建议使用 while 循环。
    • 这看起来像是我一直在寻找的解决方案。我有一个 1000 条记录的数据库,它希望每个查询最多返回 100 个结果,其中“页面”和“页面大小”是查询参数。要读取所有数据,我必须发出重复查询,增加页码,直到它回答 404 以指示没有更多可用页面。我认为您的 while 循环可以完成这项工作。如果有更好的方法可以将这些查询的结果按顺序连接起来直到 404 响应,我们可以为此打开另一个更具体的问题...(并非所有操作都适合异步操作。)
    • (我看到的其他建议涉及递归,而且我对 Javascript 执行不够了解/不信任,因此不想打赌不会炸毁内存。在其他一些语言中,我d 认为尾递归是一个优雅的解决方案。)
    • 稍作修改后,这似乎对我有用——至少,它正在运行查询循环。现在我需要解析返回的数据。 (在我的例子中,有一个 meta.pagination 部分,其中包含 page、pages 和 count;我可以使用它们来代替 dataHasMore 测试。)
    【解决方案2】:

    我认为您可以根据需要调整此示例:

    
    (async () => {
      const times = Array.from({ length: 4 }, (_, i) => i));
      let offset;
    
      for (let i of times) {
        offset = await pullWriteData(offset);
      }
    })();
    
    
    function pullWriteData(offsetValue) {
      return axios({
        method: 'get',
        url: 'https://api.hubapi.com/engagements/v1/engagements/paged',
        params: {
          hapikey: 'API_KEY_HERE',
          limit: 250,
          offset: offsetValue
        }
      }).then(response => response.data);
    }
    

    【讨论】:

      猜你喜欢
      • 2019-06-05
      • 1970-01-01
      • 2020-06-07
      • 2021-08-24
      • 1970-01-01
      • 2019-07-18
      • 2016-01-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多