.push() 在 throw 下不起作用,使用 async await 方法在 javascript 中循环获取数据

Posted

技术标签:

【中文标题】.push() 在 throw 下不起作用,使用 async await 方法在 javascript 中循环获取数据【英文标题】:.push() does not work under throw, using async await method to fetch data in a loop in javascript 【发布时间】:2021-09-29 05:02:53 【问题描述】:

我正在尝试使用 async await 依次获取数据并将 response.json 推送到数组中。但是,我在下面使用的代码不会在console.log(b); 中显示结果。有谁知道是什么问题?

提前谢谢你!

async function fetch_data()

    let b = [];
    
    for (let i = 1; i < 10; i++) 

        let response = await fetch('https://SOME_URL/' + i, 
          method: "GET",
          headers: "Key": "123456")


        if (!response.ok) 
        var error_detail = `An error has occured: $response.status`;
        throw new Error(error_detail);
        

        var data = await response.json();

        // await b.push(data);
        b.push(data);
    

    // await Promise.all(b).then(function (b) 
    //         console.log(b))

    console.log(b);
    return b;


当我运行脚本时,它不会在控制台中返回任何内容

fetch_data().catch(error => 
  error.error_detail;
);

更新:似乎使用下面的答案解决了。不知道为什么。

console.log(b); 不显示输出的问题是因为例如'https://SOME_URL/' + i 随着i 增加,如果当i = 5 返回错误,那么console.log(b); 将不会返回任何内容。如果我设置了i &lt; 5,那么console.log(b); 将返回输出b。所以这意味着如果循环中的任何 fetch 在i 的限制内返回错误,那么推送将不起作用(b 将为空),因此console.log(b); 将不会返回任何内容。

有人知道如何解决这个问题吗?

【问题讨论】:

将函数重命名为其他名称(例如_fetch) 我认为你不需要等待b.push(data)。这只是一个数组推送。 我修改了它,它仍然没有返回任何东西。 与***.com/a/60710890/1980846重复 您的代码对我来说可以正常工作。我使用https://jsonplaceholder.typicode.com/todos/1 进行测试。 【参考方案1】:

您需要重命名函数。您得到的错误是Maximum call stack size exceeded,因为当您在循环内调用fetch 时,您实际上调用的是外部函数,而不是您想要的函数。

【讨论】:

嗨 Jesper,我确实重命名了我的函数,但它仍然没有返回任何内容。 内部 fetch 永远不会调用外部循环或 fetch_data 函数,因此在这种情况下重命名不会做任何事情。【参考方案2】:

这是一个工作版本(至少它对我有用): 基本上我只是删除了标题并缩进了一点,所以你的例子应该也可以。也许您在后端有问题?

async function fetch_data() 
  let b = [];

  for (let i = 1; i < 10; i++) 
    let response = await fetch('https://jsonplaceholder.typicode.com/todos/' + i, 
      method: "GET",
    );

    if (!response.ok) 
      var error_detail = `An error has occured: $response.status`;
      throw new Error(error_detail);
    

    var data = await response.json();
    // await b.push(data);
    b.push(data);
  

  console.log(b);
  return b;


fetch_data()
  .then(data => console.log(data.length))
  .catch(err => console.error(err));

【讨论】:

这真的很奇怪。我必须添加标头,并且带有标头的 fetch 部分肯定可以正常工作,因为当我将 console.log(b) 放在 b.push(data) 之后,它确实会在控制台的每次迭代中将 json 数据推送到数组 b 大家好,我想我知道这个问题。这是因为例如 https://jsonplaceholder.typicode.com/todos/' + i 随着 i 的增加,如果当 i = 5 并且它返回错误,那么 console.log(b); 将不会返回任何内容。如果我设置 i console.log(b); 将返回 b。所以这意味着如果任何 fetch 在 i 的限制内返回错误,那么console.log(b); 将不会返回任何内容。如何解决这个问题? @ggorelen @Goran.it @SunTianyi 您可以在函数调用周围使用 try/catch。或者,您可以将一些内容推送到结果数组中,以指示发生了错误(error: true),而不是引发错误。一旦你抛出一个错误,脚本就会停止,你将无法返回任何东西。【参考方案3】:

throw new Error(error_detail); 更改为break 似乎解决了问题并能够显示结果。

【讨论】:

【参考方案4】:

我更新了几个地方 问题之一是函数名称:“fetch”与默认的 fetch 函数名称相同。

const fetchData = async(symbol) => 
  try 
    let promiseGroup = [];

    const subFetch = async(i) => 
      const BASE_URL = `https://reqres.in/api/products`
      return fetch(`$BASE_URL/$i`, 
        method: "GET",
        headers: 
          "Key": "123456"
        
      ).then(res => res.json())
    

    for (let i = 1; i < 10; i++) 
      promiseGroup.push(i);
       
    const results = await Promise.all(promiseGroup.map(subFetch))
    console.log(results)
    return result;

   catch (error) 
    const error_detail = `An error has occured: $error`;
    throw new Error(error_detail);
  

console.log(fetchData())

【讨论】:

以上是关于.push() 在 throw 下不起作用,使用 async await 方法在 javascript 中循环获取数据的主要内容,如果未能解决你的问题,请参考以下文章

为啥消息处理程序在调试模式下不起作用?

为啥切片函数在不明确使用 dplyr 的情况下不起作用

为啥 DragDrop 在 VS2010 下不起作用?

使用 libcurl 构建项目在 linux 下不起作用

输入类型=“日期”在引导模式下不起作用

.htaccess 在 xampp 和 Ubuntu 下不起作用