我正在研究一个读取CSV文件并在文件上的每一行发送请求的组件。该过程运行良好,但是随着线路成功发布,我试图显示反馈。问题在于,使用useState挂钩时,set函数在调用函数的那一刻就传递了,而不是在每个promise被解决后才传递。因此,我无法追加到成功的结果数组中,该数组不断被上次成功调用替换。API调用会被反跳一秒钟,以防止服务器过载。
import React, {useState} from "react";
import CSVReader from "react-csv-reader";
import {post} from "../api";
function App() {
const [inserts, setInserts] = useState([])
const callApi = async (x) => {
let item = {
date: x.date,
value: x.value,
};
await post(`add-items`, item);
setInserts([...inserts, item])
};
const debouncedApiCall = (body, delay) => {
return new Promise((resolve) => {
const handler = () => callApi(body).then((x) => resolve(x));
setTimeout(handler, delay);
});
};
const insert = async (rows) => {
let timer = 0;
await Promise.all(
rows.map(async (x) => {
timer++;
return await debouncedApiCall(x, timer * 1000);
})
);
};
let onFileLoaded = (data) => {
insert(data).then((x) => console.log(x));
};
return (
<div>
<CSVReader onFileLoaded={onFileLoaded}/>
{JSON.stringify(inserts)}
</div>
);
}
export default App;
调用您的调用API函数时,它会在其闭包内捕获的状态inserts
。这意味着,这inserts
并不总是最新的。您最终得到的结果称为“ 过时的关闭 ”。
为了解决这个问题,useState方法提供的mutation函数可以接受回调函数。调用函数时,该回调函数可以接收最新状态。这对异步操作很有帮助。
您的callApi函数将变为
const callApi = async (x) => {
let item = {
date: x.date,
value: x.value,
};
await post(`add-items`, item);
setInserts(prevState => [...prevState , item]) //prevState gets the latest state of inserts when setInserts is called
return (x); //will return this value once this async function finishes. similar to resolve(x)
};
我无法完全调试您的代码,但我认为这是不必要的步骤。您应该能够更改插入函数以等待所有callApi的调用,并且只需从callApi函数返回x(如我在上面添加的内容)。
const insert = async (rows) => {
let timer = 0;
await Promise.all(
rows.map((x) => {
return callApi(x); //Promise.All wants an array of promises. async functions return a promise
})
);
};
附带说明,Promise.all返回一个promise,其中包含所有promise结果的实际数组结果。您可以通过在Promise.All中添加.then来获取它们,并从insert函数中删除异步,或等待结果。
基于异步: insert返回一个promise,因此您需要在调用函数中进行处理。
const insert = async (rows) => {
let timer = 0;
const results = await Promise.all(
rows.map((x) => {
return callApi(x); //Promise.All wants an array of promises. async functions return a promise
})
);
return results; //array of all your x values for each row
};
基于非异步:行尾,insert是调用函数
const insert = (rows) => {
let timer = 0;
Promise.all(
rows.map((x) => {
return callApi(x); //Promise.All wants an array of promises. async functions return a promise
})
).then((result) => {
//result is an array of all x values according to rows
});
};
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句