如何在不使用setTimeout的情况下从axios请求中获取数据?

时间:2020-02-16 07:18:12

标签: reactjs redux react-redux axios

我遇到了问题,我相信你们中的许多人都已经遇到了问题,所以我使用const data = require("./path/to/your/json/file"); const averageTs = data.reduce((acc, current) => acc + current.ts, 0)/data.length; const averageCpu = data.reduce((acc, current) => acc + current.cpu, 0)/data.length; // do the same for other values 来获取数据:

axios

类似这样的情况,响应数据返回8个项目的数组,但是 let data = axios.get( "http://localhost:8080/api/taskExecution?&search=&page=1&size=8" ).then(response => { if (response.status !== 200) { console.log("LOADING"); } else { return response.data; } }); let tasks = []; data.then(response => { tasks = response; }); console.log(tasks); return tasks; 仍然是空的,这是正常的,因为tasks请求需要一些时间,我可以使用setTimeout持续100ms并在其中使用将axios放进去就可以了,但这不是一个合适的解决方案,因为如果服务器花5秒钟的时间返回数据怎么办?

此代码在我的reducer中,因此我必须获取console.log(tasks);并返回它们,以便我可以显示它们,并在执行请求时显示加载程序。

这是我的减速机:

tasks

我需要这段代码以及它的概念方面的帮助,我的意思是我应该在哪里更改加载程序状态等等。

3 个答案:

答案 0 :(得分:1)

我想您可以花一些时间来了解Promises和async / awiat

例如:如果执行此操作,控制台将列出所有任务。

 data.then(response => {
   tasks = response;
   console.log(tasks);
 });

原因是您传递给诺言的.then函数的函数不会立即执行,它会在Promise解决后立即执行(在您的情况下,完成http请求的执行)。

要获得更多逐行执行的感觉,您可以使用async / await

  let tasks = await Axios.get("http://localhost:8080/api/taskExecution?&search=&page=1&size=8")
    .then(response => {
      if (response.status !== 200) {
         console.log("LOADING");
      } else {
         return response.data;
      }
    });
    console.log(tasks);
    return tasks;

要注意的是,您只能在异步函数中使用await https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

答案 1 :(得分:1)

好的哥们,所以我想提出几件事:

首先,您应该始终使用您的reducer仅将新状态返回给Redux,仅此而已。您只需合并来自操作的新数据和您的旧状态,然后将其返回即可。而且您不能在其中使用Promiseasync/await,因为Redux也不支持这种行为。

第二,所有业务逻辑应置于您的操作中。数据获取(如您的情况),计算和诸如此类的东西都需要采取行动。现在,您到了很可能应该开始使用redux-thunkredux-saga之类的库来处理动作中的异步操作的地步。 redux-thunkredux-saga复杂,但是redux-saga为您提供了许多很酷的功能,但可能有点复杂。

无论是哪种方式,您都可以大做大,也可以从小做起,它们会迫使您将获取数据的动作转移到行动中。如果要支持数据加载,则只需调度告诉Redux的操作:“我正在加载数据”或“加载数据时出错”或“我已加载数据”。当执行该操作时,请更新您的商店,显示加载程序,数据或根据需要显示错误。您可以查看使用redux-thunk进行数据提取的thisthat示例,这是您开始异步操作所需的一切。

希望对您有帮助<3

答案 2 :(得分:0)

正如在其他答案中提到的那样,我将设置我的reducer仅用于处理状态更新,而设置动作创建器功能以获取数据。如果要这样做,这是最小的起点。您可以使用加载状态显示加载微调框或进度条。

我的动作创建者函数以及各个动作:

config

并且reducer将按如下方式处理状态更新:

export const GET_TASKS_START = "GET_TASKS";
export const GET_TASKS_SUCCESS = "GET_TASKS_SUCCESS";
export const GET_TASKS_FAILURE = "GET_TASKS_FAILURE";

export const getData = () => dispatch => {
  dispatch(GET_TASKS_START);
  axios
    .get("http://localhost:8080/api/taskExecution?&search=&page=1&size=8")
    .then(response => {
      dispatch({ type: GET_TASKS_SUCESS, payload: response.data });
    })
    .catch(err => {
      dispatch({ type: GET_TASKS_FAILURE, payload: err.response });
    });
};

我建议控制台记录日志并检查响应(数据和错误),并相应地修改这两个功能