Извлечение большого объема данных с помощью цикла или рекурсии с процентом прогресса в React / React native - PullRequest
5 голосов
/ 19 марта 2019

Привет, я пишу собственное приложение реакции от версии для Android 4.4.4 до последняя . У меня есть ситуация, когда нужно загрузить миллионов записей, а затем сохранить в локальной базе данных ( с использованием арбузной базы данных ). Я делаю записи на страницы и получаю данные с помощью запроса xhr (10000 за один раз).

Извлечение и хранение оба являются асинхронными операциями. я могу сделать это с помощью цикла или рекурсии.

Фрагмент рекурсии:

dataFetch = async () => {
    if (maxPages && page > maxPages) {
      return true;
    }
    const { data } = await axios.get(API_GET_RECORDS, {
      params: {
        page,
        per_page: 10000,
      },
    });
    if (data.data && data.data.length === 0) {
      return true;
    }
    await addIntoDatabase(this.props.database, data.data);
    if ((maxPages || data.max_pages) && page) {
      this.setState({
        message: `Loading ${Number.parseFloat(
          (page * 100) / (maxPages || data.max_pages),
        )}%`,
      });
      // console.log((page * 100) / (maxPages || data.max_pages));
    }
    return this.dataFetch(page + 1, data.max_pages);
  };

Фрагмент петли

dataFetch = async () => {
    let page = 1;
    let maxPages;
    do {
      const { data } = await axios.get(API_GET_RECORDS, {
        params: {
          page,
          per_page: 10000,
        },
      });
      await addIntoDatabase(this.props.database, data.data);
      if (data.max_pages && page) {
        this.setState({
          message: `Loading ${Math.round((page * 100) / data.max_pages)}%`,
        });
      }
      page += 1;
      maxPages = data.max_pages;
    } while (page < maxPages);
  };

вызов функции

downloadMyDataAndDoOtherTask = () => {
 // ... some task
 dataFetch(); // you should get all the data then start executing next line
 // ... some other task depends on this task;
}
  1. Каков наилучший цикл подхода или рекурсия в такой ситуации?

  2. Реагирует, когда мы устанавливаем setState в любом виде циклов или рекурсии, тогда он не будет обновляться немедленно ( Концепция пакетного обновления ). Если я хочу показать процент прогресса в этом случае, как я могу показать. Потому что реакция не будет обновляться во всех итерациях, поэтому прогресс будет отставать от фактического прогресса.

Заранее спасибо.

Редактировать

В обоих случаях (зацикливание и рекурсия) после загрузки около 2-3 недостатков данных приложение перестало работать.

1 Ответ

0 голосов
/ 19 марта 2019

Вы можете использовать рекурсивный метод и использовать обратный вызов setState для следующей итерации:

dataFetch = async () => {
  // ...
  this.setState({
    message: `Loading ${Number.parseFloat(
      (page * 100) / (maxPages || data.max_pages),
    )}%`,
  }, () => {
    InteractionManager.runAfterInteractions(() => {
      this.dataFetch(page + 1, data.max_pages);
    });
  });
};

Таким образом, он сначала установит ваш прогресс в состоянии и продолжит выборку после обновления состояния.

...