D
D
DarthJS2018-06-05 09:37:10
JavaScript
DarthJS, 2018-06-05 09:37:10

How to wait for all data given React Redux Async Recursion construct?

There is a file actionsin which there are asynchronous requests, but one request needs to be made recursive so as not to send a huge request, but to take it in small pieces. Everything seems to be nothing, but only the drawing comes faster than the last piece is saved in the ReduxState
Example:

myRecursion = (cb) => {  // Рекурсивная функция, которую будем вызывать дальше при выполнении реквеста
 return new Promise(() => {
  Api
   .getSomeData(request)
   .then(response => {
     dispatch(actionHandler(response.item)) // Диспатчим новые айтемы
      if(response.items.length){
         myRecursion(); // Если есть еще данные, вызываемся снова
         return false;
       }
        return true;
   })
   .then(() => cb()) // Вызываем колбек, который является resolve, чтоб зарезолвить промис.
 })
}

// Ниже главные функционал реквестов
const promise = new Promise(resolve => {
const requests = someData.reduce() // тут собирается пачка реквестов

Promise
  .all(requests) // резолвим все реквесты
  .then(response => {
    response.forEach((item, i) => {
     dispatch(actionHandler(item)); // Диспатчим, всё ок
       if(item.type определенного типа мы его загоняем в рекурсию){ // необходимое условие для определенного реквеста
         myRecursion(resolve) // Та самая рекурсия. Я решил запихнуть туда resolve, чтоб его вызвать колбеком по завершению всех следующих реквестов
        }
    })
   });
});
promise.then(() => {
 // По идее все реквесты закончились, но последний резвест не успевает сохраниться в Redux State, и отрисовка некоторых данных получается некорректная, все предыдущие запросы рисуются отлично
})

Anyone have any ideas what I did wrong?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Spirin, 2018-06-05
@DarthJS

Why do you need recursion? Looks like a set of crutches. Try to solve the problem in a different way. For example, pick up data in one request, or implement an infinite scroll with data loading on demand.
The redraw happens when you update the store . Nothing surprising.
If so you want to leave and use your approach. You have two ways:
1. Add the isAllDataLoaded key to the store and update it in the reducer when the last piece of data arrives.
2. Add redux-thunk to the project to the project . Rewrite your function in async action :

const fetchData = () => async dispatch => {
  const data = [];
  try {
    while(true) {
      const response = await Api.getSomeData({ from: data.length });
      data.push(response.item); // если item это массив, то data.push(...response.item); 
      if(!response.items.length) {
        break;
      }
    }
    
    dispatch(fetchDataSuccess(data));
    
    return data;
  } catch (e) {
    dispatch(fetchDataFail(e));
  }
};

Also learn to write maintainable and readable code. Follow the community standards, such requests, when using redux , are usually taken out in an async action or saga .
In API принято реализовывать эндпоинты для получения как одного экземпляра данных, так и целой коллекции.
Возможно, вам стоит написать эндпоинт для получении всей коллекции данных. Потому что сейчас ваш код выглядит как набор костылей, написанных, в попытке заполнить именно эту брешь в API.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question