axios 影响React 18 -花很长时间进行API调用

wh6knrhe  于 12个月前  发布在  iOS
关注(0)|答案(2)|浏览(149)

我试图使7个API调用的时候,组件挂载和快速获取数据,然后继续作出API调用的3个方法getTemp,getGPU,getMemory的每一个。虽然它需要约20秒,以获得1个API调用。
我看着我的后端和一切工作正常,电话收到并正确回应
我试图删除asyc调用,但没有工作
详细说明:现在:

  • 刷新页面->后端API被3次调用命中->控制台或浏览器中不显示任何内容
  • 20秒后->我的所有状态数组都为空
  • 大约25秒后->数组有1个条目
  • 1秒后->数组开始有多个条目,因为他们应该和工作正常

我想要的是:

  • 点击刷新按钮->服务器API需要点击7次
  • 然后每隔一秒打一个电话
  • 不想等待20或25秒才填充第一个数组

从Network选项卡中,我不断获取所有挂起的API调用:
x1c 0d1x的数据
最后,它清理,但它需要2至3分钟开始清理



你能帮助我们只调用一次7个API,并且每秒调用1个API吗?

import { Card, Metric, CategoryBar, Flex, Text, AreaChart, ProgressBar, Title, LineChart } from "@tremor/react";
import card_1 from '../assets/cards/card_1.json'
import card_2 from '../assets/cards/card_2.json'
import card_3 from '../assets/cards/card_3.json'
import card_4 from '../assets/cards/card_4.json'
import React, { useState, useEffect } from 'react';
import axios from 'axios';

var all_cards_array = [card_1, card_2, card_3, card_4]
var array_of_temperatures = []
var array_of_gpu_usage = []
var array_of_gpu_memory = []
const array_of_colors = [
    "slate",
    "gray",
    "zinc",
    "neutral",
    "stone",
    "red",
    "orange",
    "amber",
    "yellow",
    "lime",
    "green",
    "emerald",
    "teal",
    "cyan",
    "sky",
    "blue",
    "indigo",
    "violet",
    "purple",
    "fuchsia",
    "pink",
    "rose"
];

var startTime, endTime;

var optionCelsius = {
    style: 'unit',
    unit: 'celsius'
};

var optionPercent = {
    style: 'percent',
    minimumFractionDigits: 0,
    maximumFractionDigits: 0
};

axios.defaults.baseURL = 'http://url';
const valueFormatterPercentage = (number) => `${new Intl.NumberFormat("en-US", optionPercent).format(number / 100).toString()}`;
const valueFormatterCelcius = (number) => `${new Intl.NumberFormat("en-US", optionCelsius).format(number).toString()}`;

const Dashboard = () => {
    const [temperatures, setTemperatures] = useState(null);
    const [gpuUsage, setGpuUsage] = useState(null);
    const [gpuMemory, setGpuMemory] = useState(null);
    const [count, setCount] = useState(10);

    const getTemps = async () => {
        try {
            const { data } = await axios.get('/temperature_info');
            await setTemperatures(data);
            converTemperatureJsonToArray()
            console.log('Temps')
            console.log(array_of_temperatures)
            console.log(temperatures)

            return data
        } catch (err) {
            console.error(err);
        }
    };

    const getGpuUsage = async () => {
        try {
            const { data } = await axios.get('/gpu_usage_info');
            await setGpuUsage(data);
            converGpuJsonToArray()
            console.log('Gpu Usage')
            console.log(array_of_gpu_usage)
            console.log(gpuUsage)

            return data
        } catch (err) {
            console.error(err);
        }
    };

    const getGpuMemory = async () => {
        try {
            const { data } = await axios.get('/memory_usage_info');
            await setGpuMemory(data);
            converMemoryJsonToArray()
            console.log('Memory')
            console.log(array_of_gpu_memory)
            console.log(gpuMemory)

            return data
        } catch (err) {
            console.error(err);
        }
    };

    const countDown = () => {
        const interval = setInterval(function () {
            setCount((prev) => prev - 1);
        }, 1000);
    };

    useEffect(() => {
        getTemps()
        getGpuUsage()
        getGpuMemory()
        gpuUsageKeys()
        gpuMemoryKeys()
        temperaturesKeys()
        // countDown()

    }, [temperatures, gpuUsage, gpuMemory]);

    function start() {
        startTime = new Date();
    }

    function end() {
        endTime = new Date();
        var timeDiff = endTime - startTime; //in ms
        // strip the ms
        timeDiff /= 1000;

        // get seconds 
        var seconds = Math.round(timeDiff);
        console.log(seconds + " seconds");
    }

    function select_random_color(array_lenght) {
        const list_colors = []
        for (i in array_lenght) {
            list_colors.push(array_of_colors[Math.floor(Math.random() * array_lenght)])
        }

        return list_colors
    }

    function temperaturesKeys() {
        if (temperatures) {
            console.log('In keys temperatures')
            var list_keys = []

            for (const key of Object.keys(temperatures)) {
                if (key !== 'time_stamp') {
                    list_keys.push(key)
                }
            }

            return list_keys
        }

        return null
    }

    function gpuUsageKeys() {
        if (gpuUsage) {
            console.log('In keys gpu')
            var list_keys = []

            for (const key of Object.keys(gpuUsage)) {
                if (key !== 'time_stamp') {
                    list_keys.push(key)
                }
            }

            return list_keys
        }

        return null
    }

    function gpuMemoryKeys() {
        if (gpuMemory) {
            console.log('In keys memory')
            var list_keys = []

            for (const key of Object.keys(gpuMemory)) {
                if (key !== 'time_stamp') {
                    list_keys.push(key)
                }
            }

            return list_keys
        }

        return null
    }

    function getTemperatureFormattedJson() {
        const currentDate = new Date().toLocaleTimeString()
        const dict = {}

        for (const key of Object.keys(temperatures)) {
            if (key === 'time_stamp') {
                dict[key] = currentDate
            } else {
                dict[key] = temperatures[key]
            }
        }

        return dict
    }

    function getGpuFormattedJson() {
        const currentDate = new Date().toLocaleTimeString()
        const dict = {}

        for (const key of Object.keys(gpuUsage)) {
            if (key === 'time_stamp') {
                dict[key] = currentDate
            } else {
                dict[key] = gpuUsage[key]
            }
        }

        return dict
    }

    function getMemoryFormattedJson() {
        const currentDate = new Date().toLocaleTimeString()
        const dict = {}

        for (const key of Object.keys(gpuMemory)) {
            if (key === 'time_stamp') {
                dict[key] = currentDate
            } else {
                dict[key] = gpuMemory[key]
            }
        }

        return dict
    }

    function converTemperatureJsonToArray() {
        if (temperatures) {
            if (array_of_temperatures.length > 7) {
                array_of_temperatures.splice(0, 1)
            }

            array_of_temperatures.push(getTemperatureFormattedJson())

            return array_of_temperatures
        }

        return [""]
    }

    function converGpuJsonToArray() {
        if (gpuUsage) {
            if (array_of_gpu_usage.length > 7) {
                array_of_gpu_usage.splice(0, 1)
            }

            array_of_gpu_usage.push(getGpuFormattedJson())

            return array_of_gpu_usage
        }

        return [""]
    }

    function converMemoryJsonToArray() {
        if (gpuMemory) {
            if (array_of_gpu_memory.length > 7) {
                array_of_gpu_memory.splice(0, 1)
            }

            array_of_gpu_memory.push(getMemoryFormattedJson())

            return array_of_gpu_memory
        }

        return [""]
    }

    function renderBox() {
        return (
            <div className={color}>
            </div>
        )
    }

    function uuidv4() {
        return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c =>
            (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
        );
    }

    function renderGPUName(cardName) {
        return (
            <div key={uuidv4()}>
                <h2 className='text-2xl font-bold'>
                    Gpu Name
                </h2>
                <br />
                <Card className="max-w-xs mx-auto" decoration="top" decorationColor="indigo">
                    <Metric>{cardName}</Metric>
                </Card>
            </div>
        )
    }

    function renderCards() {
        const cards = []
        var div_top_black = 'black'
        var div_top_blue = 'grid grid-cols-5 gap-14 blue'
        const list_colors = [div_top_black, div_top_blue]
        var count = 0

        for (const card of all_cards_array) {
            var color = ''

            if (count == 0) {
                color = list_colors[0]
                count += 1
            } else {
                color = list_colors[1]
                count = 0
            }

            cards.push(
                <div key={uuidv4()}>
                    <br />
                    <br />
                    <br />
                    <br />
                </div>
            )
            cards.push(
                <div className={color} key={uuidv4()}>
                </div>
            )
            cards.push(renderGPUName(card.name))
            cards.push(
                <div key={uuidv4()}>
                    <br />
                    <br />
                    <br />
                    <br />
                </div>
            )
            cards.push(
                <div className='grid grid-cols-5 gap-14' key={uuidv4()}>
                    <div>
                        <h2 className='text-2xl font-bold'>
                            Driver Version
                        </h2>
                        <br />
                        <Card className="max-w-xs mx-auto" decoration="top" decorationColor="indigo">
                            <Metric>{card.driver_version}</Metric>
                        </Card>
                    </div>
                    <div>
                        <h2 className='text-2xl font-bold'>
                            P State
                        </h2>
                        <br />
                        <Card className="max-w-xs mx-auto" decoration="top" decorationColor="indigo">
                            <Metric>{card.pstate}</Metric>
                        </Card>
                    </div>
                    <div>
                        <h2 className='text-lg font-bold'>
                            Pcie Link Gen Max
                        </h2>
                        <br />
                        <Card className="max-w-xs mx-auto" decoration="top" decorationColor="indigo">
                            <Metric>{card.pcie_link_gen_max}</Metric>
                        </Card>
                    </div>
                    <div>
                        <h2 className='text-lg font-bold'>
                            Pcie Link Gen Current
                        </h2>
                        <br />
                        <Card className="max-w-xs mx-auto" decoration="top" decorationColor="indigo">
                            <Metric>{card.pcie_link_gen_current}</Metric>
                        </Card>
                    </div>
                    <div>
                        <h2 className='text-2xl font-bold'>
                            Temperature
                        </h2>
                        <br />
                        <Card className="max-w-sm mx-auto">
                            <Flex>
                                <Text>0 &bull; {card.temperature_gpu}C</Text>
                                <Text>200</Text>
                            </Flex>
                            <ProgressBar value={card.temperature_gpu} color="red" className="mt-3" />
                        </Card>
                    </div>
                    <div>
                        <h2 className='text-2xl font-bold'>
                            Utilization Gpu
                        </h2>
                        <br />
                        <Card className="max-w-sm mx-auto">
                            <Flex>
                                <Text>0 &bull; {card["utilization_gpu [%]"]} %</Text>
                                <Text>100</Text>
                            </Flex>
                            <ProgressBar value={card["utilization_gpu [%]"]} color="red" className="mt-3" />
                        </Card>
                    </div>
                    <div>
                        <h2 className='text-xl font-bold'>
                            Utilization Memory
                        </h2>
                        <br />
                        <Card className="max-w-sm mx-auto">
                            <Flex>
                                <Text>0 &bull; {card["utilization_memory [%]"]}%</Text>
                                <Text>100</Text>
                            </Flex>
                            <ProgressBar value={card["utilization_memory [%]"]} color="red" className="mt-3" />
                        </Card>
                    </div>
                    <div>
                        <h2 className='text-2xl font-bold'>
                            Memory Total
                        </h2>
                        <br />
                        <Card className="max-w-sm mx-auto">
                            <Flex>
                                <Text>0 &bull; {card["memory_total [MiB]"]} MiB</Text>
                                <Text>{card["memory_total [MiB]"]}</Text>
                            </Flex>
                            <ProgressBar value={card["memory_total [MiB]"]} color="red" className="mt-3" />
                        </Card>
                    </div>
                    <div>
                        <h2 className='text-2xl font-bold'>
                            Memory Free
                        </h2>
                        <br />
                        <Card className="max-w-sm mx-auto">
                            <Flex>
                                <Text>0 &bull; {card["memory_free [MiB]"]} MiB</Text>
                                <Text>{card["memory_total [MiB]"]}</Text>
                            </Flex>
                            <ProgressBar value={card["memory_free [MiB]"] / card["memory_total [MiB]"] * 100} color="red" className="mt-3" />
                        </Card>
                    </div>
                    <div>
                        <h2 className='text-2xl font-bold'>
                            Memory Used
                        </h2>
                        <br />
                        <Card className="max-w-sm mx-auto">
                            <Flex>
                                <Text>0 &bull; {card["memory_used [MiB]"]} MiB</Text>
                                <Text>{card["memory_total [MiB]"]}</Text>
                            </Flex>
                            <ProgressBar value={card["memory_used [MiB]"] / card["memory_total [MiB]"] * 100} color="green" className="mt-3" />
                        </Card>
                        <br />
                        <br />
                    </div>
                </div>
            )
        }

        return cards
    }

    return (
        <>
            <div className='grid grid-cols-1 gap-14'>
                {array_of_temperatures.length > 7 ? 'Fetched' : 'Loading... ' + count + ' seconds left'}
                <br />
                <br />
                <br />
                <br />
                <Card>
                    <Title>Cards Temperature</Title>
                    <LineChart
                        className="mt-6"
                        data={array_of_temperatures.length > 7 ? array_of_temperatures : null}
                        index="time_stamp"
                        categories={temperatures ? temperaturesKeys() : []}
                        colors={array_of_temperatures > 0 ? select_random_color(temperaturesKeys().length - 1) : ["neutral", "indigo", "orange", "green"]}
                        valueFormatter={valueFormatterCelcius}
                        yAxisWidth={100}
                    />
                </Card>
            </div>
            <br />
            <br />
            <div className='grid grid-cols-1 gap-14'>
                <Card>
                    <Title>Cards Gpu Usage</Title>
                    <LineChart
                        className="mt-6"
                        data={array_of_gpu_usage.length > 7 ? array_of_gpu_usage : null}
                        index="time_stamp"
                        categories={gpuUsage ? gpuUsageKeys() : []}
                        colors={array_of_gpu_usage > 0 ? select_random_color(gpuUsageKeys().length - 1) : ["neutral", "indigo", "orange", "green"]}
                        valueFormatter={valueFormatterPercentage}
                        yAxisWidth={100}
                    />
                </Card>
            </div>
            <br />
            <br />
            <div className='grid grid-cols-1 gap-14'>
                <Card>
                    <Title>Cards Memory Usage</Title>
                    <LineChart
                        className="mt-6"
                        data={array_of_gpu_memory.length > 7 ? array_of_gpu_memory : null}
                        index="time_stamp"
                        categories={gpuMemory ? gpuMemoryKeys() : []}
                        colors={array_of_gpu_memory > 0 ? select_random_color(gpuMemoryKeys().length - 1) : ["neutral", "indigo", "orange", "green"]}
                        valueFormatter={valueFormatterPercentage}
                        yAxisWidth={100}
                    />
                </Card>
            </div>
            <br />
            <br />
            {renderCards()}
        </>
    )
};

export default Dashboard;

字符串

holgip5t

holgip5t1#

首先你犯了几个大错误。如果你这样使用它,你的useEffect会爆炸。
如果这些变量temperaturesgpuUsagegpuMemory中的一个发生变化, Jmeter 板组件将重新呈现自己。这会导致所有代码一次又一次地执行。这可能就是为什么你会看到你所看到的。
你可以通过获取卡中的数据来使每张卡都有状态。或者你需要看一下像Promise.all这样的东西。虽然我认为你需要让你的个人卡像<TemperatureCard><GpuUsageCard>一样有状态,这样卡就可以单独获取他们的数据,而不关心其他的。或者你可以做一个像这样的通用卡。
我添加了一些延迟,以向您展示网络延迟的样子。

const {useState,useEffect} = React;

const loadData = (data, delay) => {
  return new Promise((resolve) => {
    setTimeout(() => resolve(data), delay);
  });
}

const Widget = ({name, delay}) => {
  const [data, setData] = useState(null);
  
  const fetchData = () => {
    setData(null);
    const fetched = loadData({foo: `Data fetched for ${name}`}, delay);
    fetched.then(setData);
    setTimeout(fetchData, 1000);
  }
  
  useEffect(() => {
    fetchData();
  }, [name])
  
  
  if (null === data) {
     return <div>Loading...</div>
  }

  return <div>{data.foo}</div>;
}

ReactDOM.createRoot(
  document.getElementById("root")
).render( <div>
  <Widget name="Temperature" delay="200" />
    <Widget name="GpuUsage" delay="400" />
  </div>
);

个字符
不要忘记在你的间隔期间添加一个AbortController。你的网络可能会响应得更慢,并且会导致一个旧的API调用被渲染。所以你必须中止它。在axios文档中可能有关于如何做的文档。
你还提到你的API需要几秒钟才能响应。这可能是你的React应用程序请求了太多的数据,这会让你的应用程序过载。React组件会和你的API调用一样快。

00jrzges

00jrzges2#

我想我不得不退一步,看看一个不同的方法来解决这个问题。我在下面添加一些参考资料来证明我的React。
首先,我们需要打破“如果你唯一的工具是锤子,你倾向于把每个问题都看作钉子”的想法。
那么什么时候使用API调用和webhooks呢?
这是一篇很好的文章,让我走上了正确的道路:Webhooks, Api Calls, Push Sub, and Websockets differences
其次,让我们实现WebSocket:

const WS_URL_ALL_INFO = 'ws://YOUR_WEBSOCKET_URL';
const socketState = 'OPEN'

const { sendJsonMessage, lastJsonMessage } = useWebSocket(WS_URL_ALL_INFO, {
    share: true,
})

    useEffect(() => {
    sendJsonMessage({ "message": socketState })

    if (lastJsonMessage) {
        console.log(lastJsonMessage)
    }
}, [jsonMessage, lastJsonMessage])

字符串
就是这样!它所需要的只是一个WebSocket,如果你愿意,你可以使用setEffect()来设置延迟,如果你愿意,你可以使用多个useEffect()和[]来运行一次多次
对于@Leroy,你使用的是轮询,在这种情况下是错误的方法,我知道我也是这么想的,然后它击中了我。轮询总是很慢,webhooks也不会工作,因为它也会很慢,因为每1秒就有一个调用。一个WebSocket打开并保持打开状态,直到你关闭它,连续地给你数据,你可以建立一个超时服务器或客户端。在这种情况下,它工作得很好。
还有:

ReactDOM.createRoot(
  document.getElementById("root")
).render( <div>
  <Widget name="Temperature" delay="200" />
    <Widget name="GpuUsage" delay="400" />
  </div>
);


在react 18中,不赞成直接使用dom
React 18中不再支持ReactDOM.render。请改用ReactRoot。在切换到新的API之前,您的应用将像运行React 17一样运行。了解更多信息:https://reactjs.org/link/switch-to-createroot
React 18

相关问题