Reactjs 对批量进程执行多个承诺后进行响应、更新

Reactjs 对批量进程执行多个承诺后进行响应、更新,reactjs,async-await,axios,react-hooks,setstate,Reactjs,Async Await,Axios,React Hooks,Setstate,我正在开发一个组件,它读取一个CSV文件,并在文件的每一行发送一个请求。这个过程非常有效,但我正试图在这些行成功发布后显示反馈。问题是,使用useState钩子,set函数在调用函数时被传递,而不是在每个承诺都得到解决之后。因此我无法附加到successful results数组,该数组一直被最后一次成功调用替换。 API调用被取消公告一秒钟,以防止服务器过载 import React, {useState} from "react"; import CSVReader fr

我正在开发一个组件,它读取一个CSV文件,并在文件的每一行发送一个请求。这个过程非常有效,但我正试图在这些行成功发布后显示反馈。问题是,使用useState钩子,set函数在调用函数时被传递,而不是在每个承诺都得到解决之后。因此我无法附加到successful results数组,该数组一直被最后一次成功调用替换。 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;
import React,{useState}来自“React”;
从“react csv reader”导入CSVReader;
从“./api”导入{post};
函数App(){
const[inserts,setInserts]=useState([]
const callApi=async(x)=>{
让项目={
日期:x.date,
值:x.value,
};
等待投递(`additems`,item);
setInserts([…inserts,item])
};
const debouncedApiCall=(主体,延迟)=>{
返回新承诺((解决)=>{
consthandler=()=>callApi(body),然后((x)=>resolve(x));
setTimeout(处理程序,延迟);
});
};
常量插入=异步(行)=>{
设定时器=0;
等待承诺(
rows.map(异步(x)=>{
定时器++;
返回等待去Bouncedapicall(x,计时器*1000);
})
);
};
设onFileLoaded=(数据)=>{
插入(数据),然后((x)=>console.log(x));
};
返回(
{JSON.stringify(inserts)}
);
}
导出默认应用程序;

调用调用API函数时,它在闭包中捕获插入的状态。这意味着,
插入
并不总是最新的。你最后得到的东西叫做“a”

为了避免这种情况,useState方法提供的变异函数可以接受回调函数。此回调函数可以在调用函数时接收最新状态。这在异步操作中很有用

您的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)
};
我不能完全调试你的代码,但我认为这是一个不必要的步骤。您应该能够将insert函数更改为等待所有的callApi,并从callApi函数返回x(正如我在上面添加的)

另外,Promise.all返回一个Promise,其中包含所有Promise结果的实际数组结果。您可以通过在Promise.All中添加.then并从insert函数中删除async来获取它们,或者等待结果

基于异步:insert返回一个承诺,因此需要在调用函数中处理该承诺

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
};
None async-based:行尾,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
    });
};

调用调用API函数时,在其闭包中捕获插入的状态。这意味着,
插入
并不总是最新的。你最后得到的东西叫做“a”

为了避免这种情况,useState方法提供的变异函数可以接受回调函数。此回调函数可以在调用函数时接收最新状态。这在异步操作中很有用

您的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)
};
我不能完全调试你的代码,但我认为这是一个不必要的步骤。您应该能够将insert函数更改为等待所有的callApi,并从callApi函数返回x(正如我在上面添加的)

另外,Promise.all返回一个Promise,其中包含所有Promise结果的实际数组结果。您可以通过在Promise.All中添加.then并从insert函数中删除async来获取它们,或者等待结果

基于异步:insert返回一个承诺,因此需要在调用函数中处理该承诺

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
};
None async-based:行尾,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
    });
};

尝试此
setInserts(prevState=>[…prevState,item])
似乎您想在设置前等待
post
返回?可能
const response=post('add-items',item);if(响应成功)setInserts([…inserts,item])尝试此
setInserts(prevState=>[…prevState,item])
似乎您想在设置前等待
post
返回?可能
const response=post('add-items',item);if(响应成功)setInserts([…inserts,item])没问题,很高兴我能帮忙:)没问题,很高兴我能帮忙:)