等待For循环中的GET请求

时间:2018-05-18 02:24:42

标签: javascript node.js asynchronous get axios

我正在尝试使用Axios和Node向Web服务器发出大量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 --> [ ]  
});

1 个答案:

答案 0 :(得分:2)

  

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

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

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

  1. 致电test()
  2. 使用axios.get()
  3. 迭代并创建每个请求
  4. 返回results
  5. .then((results) => console.log(results)被调用,results被打印为[]
  6. 进程检查是否正在等待任何异步工作 - 没有等待任何事情
  7. 流程退出
  8. 即使您的一个请求已被处理,它至少会占用事件循环的下一个回合。但是,由于您的代码在偶数循环的单圈中执行,它会运行您编写的所有代码,但附加到axios.get()的响应处理程序除外。如果您想更详细地解释事件循环每回合发生的事情以及它们如何运作,您可以阅读更多相关信息here

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

    使用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))