Как получить данные из моего запроса ax ios без использования setTimeout? - PullRequest
0 голосов
/ 16 февраля 2020

У меня проблема, я думаю, что многие из вас как-то сталкивались с этим, поэтому я использую axios для получения моих данных:

 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;

Примерно так: данные ответа возвращают массив из 8 элементы, но tasks все еще пусто, что является нормальным, потому что запрос axios занимает некоторое время, я могу использовать setTimeout в течение 100 мс, а внутри него я помещаю console.log(tasks);, и он будет работать, но это не является правильным решением, потому что если серверу нужно 5 секунд, чтобы вернуть данные?

Этот код находится в моем редукторе, поэтому я должен получить свои tasks и вернуть их, чтобы я мог их отобразить и показать загрузчик при выполнении запроса.

Это мой редуктор:

import update from "immutability-helper";
import Axios from "axios";

export default function getTasksReducer(state = [], action) {
  switch (action.type) {
    case "GET_TASKS":
      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;
    default:
      return state;
  }
}

Мне нужна помощь в этом коде, а также в его концепции, я имею в виду, где я должен изменить свое состояние загрузчика и т. д.

Ответы [ 3 ]

1 голос
/ 16 февраля 2020

Хорошо, приятель, так что я хочу поднять несколько вещей:

Во-первых, вы должны всегда использовать ваши редукторы, только возвращать новое состояние в Redux, и все. Вы просто объединяете новые данные, полученные в результате действий, со своим старым состоянием и возвращаете их обратно. И вы не можете использовать Promise или async/await там, потому что Redux не поддерживает и не будет поддерживать это поведение.

Во-вторых, все бизнес-логики c должны быть помещенным в ваши действия. Выбор данных (как в вашем случае), вычисления и тому подобное должны быть в действиях. И теперь вы подошли к тому моменту, когда вам, скорее всего, следует начать использовать библиотеки типа redux-thunk или redux-saga для обработки асинхронных операций в ваших действиях. redux-thunk менее сложен, чем redux-saga, но redux-saga наделяет вас множеством интересных функций, но это может быть немного сложнее.

Вы можете go большой или начать с малого с этих библиотек, либо Кстати, они заставят вас переместить ваши данные в ваши действия. Если вы хотите поддерживать загрузку данных, просто отправьте действия, которые сообщают Redux: «Я загружаю данные» или «Я получил ошибку при загрузке данных» или «Я загрузил данные». И когда это действие произойдет, обновите свой магазин, покажите загрузчик, данные или ошибку, если вам нужно. Вы можете взглянуть на этот или , который пример использования redux-thunk для извлечения данных, есть все, что вам нужно, чтобы начать работу с асин c действиями.

Надеюсь, это поможет <3 </p>

1 голос
/ 16 февраля 2020

Полагаю, вы можете потратить некоторое время на понимание 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 только внутри функции asyn c https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

0 голосов
/ 16 февраля 2020

Как упоминалось в других ответах, я бы настроил свой редуктор только для обработки обновления состояния и функции создателя действий для извлечения данных. Вот минимальная отправная точка, если бы я это сделал. Вы можете использовать состояние загрузки для отображения счетчиков загрузки или индикаторов выполнения.

Моя функция создателя действий с отдельными действиями:

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 });
    });
};

и редуктор будет обрабатывать обновление состояния следующим образом:

import {
  GET_TASKS_SUCCESS,
  GET_TASKS_FAILURE,
  GET_TASKS_START
} from "./Action.js";

const initialState = {
  tasks: [],
  error: null,
  loading: false
};
export default function tasksReducer(state = initialState, action) {
  switch (action.type) {
    case GET_TASKS_START:
      return {
        ...state,
        loading: true
      };
    case GET_TASKS_SUCCESS:
      return {
        ...state,
        loading: false,
        tasks: action.payload, 
        error: null
      };
    case GET_TASKS_FAILURE:
      return {
        ...state,
        loading: false,
        error: action.payload
      };
  }
}

Я бы предложил войти в консоль и проверить ответы (данные и ошибки) и соответственно изменить две функции

...