【问题标题】:Waiting For GET Requests in For Loop在 For 循环中等待 GET 请求
【发布时间】:2018-05-18 02:24:41
【问题描述】:

我正在尝试使用 Axios 和 Node.js 向网络服务器发出一些 GET 请求。我使用异步函数获取一组值,向同一网站上的唯一 URL 发出请求。

每次循环运行时,我都会将响应推送到一个名为“results”的数组中。

当循环结束时,异步函数结束,我添加一个.then 函数,将返回值传递给它。然后我将其记录到屏幕上。

我的问题是 return 语句在我的请求运行之前触发。换句话说,记录了一个空数组,然后所有请求都完成了。

如何在 GET 请求完成后才将我的 for 循环的结果返回给异步函数,并且数组中填充了值?

感谢您的帮助,代码如下:

const axios = require("axios");

var loop = [about,home,products,thanks]
var i;

const results = [];

const test = async () => {
    for(i = 0; i < loop.length; i++) {
        axios.get(`https://examplewebsite.com/${loop[i]}`)
            .then((response,body) => {
                results.push(response);
            })
            .catch((error) => {
                console.log(error)
            });
    };
    // THIS IS NOT CORRECT, IT CAUSES MY RESULTS TO BE RETURNED IMMEDIATELY
    return results;
}

test().then((results) => {
    console.log(results); // Currently outputs --> [ ]  
});

【问题讨论】:

  • 您缺少 await 关键字

标签: javascript node.js asynchronous get axios


【解决方案1】:

我的问题是 return 语句在我的请求运行之前触发。换句话说,记录一个空数组,然后完成所有请求。

您没有保留对使用 axios.get() 创建的每个 Promise Chain 的引用,因此您无法等待它们。

初始化后,上面的代码执行如下:

  1. 致电test()
  2. 使用axios.get() 迭代并创建每个请求
  3. 返回results
  4. .then((results) =&gt; console.log(results) 被调用,results 被打印为 []
  5. 进程检查是否有任何异步工作正在等待 - 没有任何等待
  6. 进程退出

至少要在事件循环的下一轮才能处理您的一个请求。但是,由于您的代码在偶数循环的单圈中执行,它会运行您编写的所有代码,除了附加到axios.get() 的响应处理程序。如果您想更详细地了解事件循环的每一轮会发生什么以及它是如何工作的,您可以阅读更多关于它的信息here

您需要返回对从axios.get() 返回的每个 Promise 的引用。与其将它们的响应存储在数组中,不如存储来自axios.get() 的 Promises。即使您使用 async/await 语法,您仍然需要使用 Promise.all() 来一次等待多个 Promise。 Promise.all() 可用于等待存储在您的数组中的所有请求承诺链。

上面的代码可以更简洁地使用Array#map 来遍历项目列表并返回一个Promise 结果数组。

const axios = require("axios");

const baseURL = 'http://examplewebsite.com/'        
const requestList = items => Promise.all(
  items.map(key => (
    axios.get(`${baseUrl}${key}`)
      .catch(err => console.error(err))
  )
)

requestList(['about', 'home', 'products', 'thanks'])
  .then(results => console.log(result))
  .catch(err => console.error(err))

【讨论】:

  • 您是不是忘记了括号?它不适合我。
猜你喜欢
  • 2021-11-04
  • 2023-01-20
  • 2018-06-09
  • 2018-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多