反应钩子,在批量处理执行了多个promise后更新

aolivera:

我正在研究一个读取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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章