尝试使用 JavaScript 获取 CSV 数据时出现无休止的 promise 循环
Endless promise loop when trying to fetch CSV data with JavaScript
我知道有很多关于如何使用异步函数的提取和 returning 承诺的帖子。我读过您应该将依赖于获取的 data/content 的代码位移动到函数中,但我看不出我的设置如何实现。因此,在您将我的问题作为重复问题关闭之前,我要求您完整阅读它并尝试记住当您刚接触编程并需要一些帮助时的情况。
我正在构建一个 React 应用程序,我想在其中根据用户输入绘制一堆 CSV 数据。我正在尝试获取 CSV 数据,提取我想要的两个变量,然后将其传递到 VictoryChart 中。这段代码成功获取数据,将其转换为由记录分隔的数组,然后创建一个新的对象数组(VictoryChart 需要的数据输入),其中只有两个字段是我的变量:
async function getData(filePath) {
let dataArray = []
await fetch(filePath)
.then(response => {
return response.text()
})
.then(data => CSVToArray(data))
.then(data => {
for (let i in data) {
dataArray.push(
{ DateTime: data[i][0], OATemp: data[i][1]}
)
};
return dataArray
})
.catch(error => alert(error))
}
根据多个消息来源的建议,我打算尝试将 VictoryChart 放入 return dataArray 之后的函数中,以将依赖于该函数的所有内容保留在函数中,但我不知道该怎么做可以通过尝试调用然后生成图形的函数来控制我的页面布局。我不明白你是如何用它构建 DOM 的(我什至用对了吗?)。我是 React 的新手(通常是一个没有经验的程序员)所以这可能是问题的一部分。
对我来说唯一有意义的是 return 数据的异步函数,这样我就可以将它传递到 VictoryChart 中。但是似乎不可能从函数中提取任何 returned 的东西,而不是它被包装到的承诺。我被告知要使用 .then
,但这只是 return 一个承诺。看起来很乱伦......具体来说,我最近的尝试看起来像这样(只是使用警报来“查看”发生了什么):
alert(getData('./2021WeatherData.csv').then(data => {return data}))
希望是,我只是不明白如何按照其他人的建议正确使用 .then
。我花了很多很多时间来尝试这个问题的几十个不同版本,并用谷歌搜索我能想到的问题的每个同义词。我知道我遗漏了一些东西,所以我很感激任何帮助。
***提供附加代码
以下是我对我的 React 应用程序的 DOM 的理解(请纠正我在措辞等方面的错误)。这会将我的应用呈现给浏览器。
return (
<div className="App">
<header className="App-header">
<div className='Header-button-container'>
<button onClick={() => alert('Weather')}>
Weather
</button>
<button onClick={() => alert('1st Floor')}>
1st Floor
</button>
<button onClick={() => alert('2nd Floor')}>
2nd Floor
</button>
</div>
</header>
<VictoryChart>
<VictoryLine data={getData('./2021WeatherData.csv').then(data => { return data })} x='DateTime' y='OATemp' />
</VictoryChart>
</div>
);
对我来说,这决定了页面上的显示方式。我注意到这里的所有内容都是一个标签,所以我不明白如何在 VictoryLine 标签存在的地方插入一个函数。 VictoryLine 图的“数据”属性需要数据作为对象数组,这就是我试图从我的 getData 函数输出的内容(但它一直被包裹在一个该死的承诺中!!)。我能够使用我在应用程序中声明的虚拟数据集使其正常工作,但在尝试获取数据时我被卡住了。而且由于我无法从函数中“取出”数据(似乎所有可能的事情都在函数内部进行),所以我陷入了困境和困惑。此处的目的是能够单击一个按钮并将相关数据提取到图形中。
听起来您只是在将 CSV 结果传递给绘图函数时遇到了问题。首先,您需要 return 来自 getData
的值;目前没有 returning 任何东西:
async function getData(filePath) {
let dataArray = []
return fetch(filePath)
...
}
然后您可以通过以下两种方式之一传递您的结果:
function theGraphFunction(data) {
// this graphs your data
}
getData("./path/to/data.csv").then(data => theGraphFunction(data));
或
(async () => {
const data = await getData("./path/to/data.csv");
theGraphFunction(data);
})()
现在您已经更新了您的问题以包含有关您实际尝试做的事情的信息,您可以这样做:
import {useEffect, useState} from "react";
function App() {
const [graphData, setGraphData] = useState(null);
useEffect(() => {
getData("./path/to/data.csv").then(data => setGraphData(data));
}, [])
// only include this if you don't want to render the component
// until data is loaded
if(!graphData) {
return null;
}
return (
<div className="App">
<header className="App-header">
<div className='Header-button-container'>
<button onClick={() => alert('Weather')}>
Weather
</button>
<button onClick={() => alert('1st Floor')}>
1st Floor
</button>
<button onClick={() => alert('2nd Floor')}>
2nd Floor
</button>
</div>
</header>
<VictoryChart>
<VictoryLine data={graphData} x='DateTime' y='OATemp' />
</VictoryChart>
</div>
);
}
我知道有很多关于如何使用异步函数的提取和 returning 承诺的帖子。我读过您应该将依赖于获取的 data/content 的代码位移动到函数中,但我看不出我的设置如何实现。因此,在您将我的问题作为重复问题关闭之前,我要求您完整阅读它并尝试记住当您刚接触编程并需要一些帮助时的情况。
我正在构建一个 React 应用程序,我想在其中根据用户输入绘制一堆 CSV 数据。我正在尝试获取 CSV 数据,提取我想要的两个变量,然后将其传递到 VictoryChart 中。这段代码成功获取数据,将其转换为由记录分隔的数组,然后创建一个新的对象数组(VictoryChart 需要的数据输入),其中只有两个字段是我的变量:
async function getData(filePath) {
let dataArray = []
await fetch(filePath)
.then(response => {
return response.text()
})
.then(data => CSVToArray(data))
.then(data => {
for (let i in data) {
dataArray.push(
{ DateTime: data[i][0], OATemp: data[i][1]}
)
};
return dataArray
})
.catch(error => alert(error))
}
根据多个消息来源的建议,我打算尝试将 VictoryChart 放入 return dataArray 之后的函数中,以将依赖于该函数的所有内容保留在函数中,但我不知道该怎么做可以通过尝试调用然后生成图形的函数来控制我的页面布局。我不明白你是如何用它构建 DOM 的(我什至用对了吗?)。我是 React 的新手(通常是一个没有经验的程序员)所以这可能是问题的一部分。
对我来说唯一有意义的是 return 数据的异步函数,这样我就可以将它传递到 VictoryChart 中。但是似乎不可能从函数中提取任何 returned 的东西,而不是它被包装到的承诺。我被告知要使用 .then
,但这只是 return 一个承诺。看起来很乱伦......具体来说,我最近的尝试看起来像这样(只是使用警报来“查看”发生了什么):
alert(getData('./2021WeatherData.csv').then(data => {return data}))
希望是,我只是不明白如何按照其他人的建议正确使用 .then
。我花了很多很多时间来尝试这个问题的几十个不同版本,并用谷歌搜索我能想到的问题的每个同义词。我知道我遗漏了一些东西,所以我很感激任何帮助。
***提供附加代码 以下是我对我的 React 应用程序的 DOM 的理解(请纠正我在措辞等方面的错误)。这会将我的应用呈现给浏览器。
return (
<div className="App">
<header className="App-header">
<div className='Header-button-container'>
<button onClick={() => alert('Weather')}>
Weather
</button>
<button onClick={() => alert('1st Floor')}>
1st Floor
</button>
<button onClick={() => alert('2nd Floor')}>
2nd Floor
</button>
</div>
</header>
<VictoryChart>
<VictoryLine data={getData('./2021WeatherData.csv').then(data => { return data })} x='DateTime' y='OATemp' />
</VictoryChart>
</div>
);
对我来说,这决定了页面上的显示方式。我注意到这里的所有内容都是一个标签,所以我不明白如何在 VictoryLine 标签存在的地方插入一个函数。 VictoryLine 图的“数据”属性需要数据作为对象数组,这就是我试图从我的 getData 函数输出的内容(但它一直被包裹在一个该死的承诺中!!)。我能够使用我在应用程序中声明的虚拟数据集使其正常工作,但在尝试获取数据时我被卡住了。而且由于我无法从函数中“取出”数据(似乎所有可能的事情都在函数内部进行),所以我陷入了困境和困惑。此处的目的是能够单击一个按钮并将相关数据提取到图形中。
听起来您只是在将 CSV 结果传递给绘图函数时遇到了问题。首先,您需要 return 来自 getData
的值;目前没有 returning 任何东西:
async function getData(filePath) {
let dataArray = []
return fetch(filePath)
...
}
然后您可以通过以下两种方式之一传递您的结果:
function theGraphFunction(data) {
// this graphs your data
}
getData("./path/to/data.csv").then(data => theGraphFunction(data));
或
(async () => {
const data = await getData("./path/to/data.csv");
theGraphFunction(data);
})()
现在您已经更新了您的问题以包含有关您实际尝试做的事情的信息,您可以这样做:
import {useEffect, useState} from "react";
function App() {
const [graphData, setGraphData] = useState(null);
useEffect(() => {
getData("./path/to/data.csv").then(data => setGraphData(data));
}, [])
// only include this if you don't want to render the component
// until data is loaded
if(!graphData) {
return null;
}
return (
<div className="App">
<header className="App-header">
<div className='Header-button-container'>
<button onClick={() => alert('Weather')}>
Weather
</button>
<button onClick={() => alert('1st Floor')}>
1st Floor
</button>
<button onClick={() => alert('2nd Floor')}>
2nd Floor
</button>
</div>
</header>
<VictoryChart>
<VictoryLine data={graphData} x='DateTime' y='OATemp' />
</VictoryChart>
</div>
);
}