Как реализовать в angular несколько последовательных запросов Http в al oop (каждый новый запрос зависит от предыдущих результатов) - PullRequest
2 голосов
/ 16 января 2020


У меня есть таблица, которая содержит тяжелые данные для загрузки, поэтому время загрузки стало неуправляемым. Решение, которое я нашел, состояло в том, чтобы выполнить последовательное количество http-запросов, каждый из которых извлекал пакеты по 100 строк, пока не выполнил все данные в сетке. Я знаю, как реализовать 2 последовательных http-запроса с использованием concatMap, и он отлично работает, но я хотел бы иметь какое-то время l oop, которое будет проверять каждый ответ, и если текущее количество строк <общее количество строк, то подписаться на новый запрос Http , Странно, что я не нахожу никакого решения для этого, может быть, я с самого начала неправильно думаю об этом решении: D Любая помощь будет очень кстати! Заранее спасибо! </p>

Код пересылки, используемый для выполнения 2 http-запросов с использованием concatMap:

private LoadGridStringResourcesInProject(projectId: number) {
let allData: StringResource[] = [];
const batchSize = 100;

this.stringResourcesService.getStringResourcesInProject(projectId, 0, batchSize)
    .pipe(
      concatMap(firstData => {
        const stringResourcesInProject = firstData as StringResource[];

        // Loads first 100 rows on the Grid
        this.gridApi.updateRowData({ add: stringResourcesInProject });
        this.agGridService.refreshSizeColumns(this.agGrid);

        // Fetch data returned by partial Http requests
        allData = stringResourcesInProject;

        if (allData && allData.length == batchSize) {

          // Do new Http request to fetch the remaining data
          return this.stringResourcesService
            .getStringResourcesInProject(projectId, batchSize, 0);
        }

        return [];
      })
    ).subscribe(data => {
        const stringResourcesInProject = data as StringResource[];

        // Loads the remaining rows in the Grid
        this.gridApi.updateRowData({ add: stringResourcesInProject });

        // Fetch data returned by partial Http requests
        allData = allData.concat(stringResourcesInProject);
      },
      error => of(null),
      () => {
        this.agGridService.refreshSizeColumns(this.agGrid);
      });

}

1 Ответ

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

Как сказал @ Maxim1992, решение использует оператор Expand Rx JS для рекурсивного вызова! Большое спасибо @ Maxim1992!

Более подробная информация здесь: Пример

Вот код, который вы также можете использовать (надеюсь, он может помочь кому-то в будущем):

private LoadGridStringResourcesInProject(projectId: number) {
const batchSize = 1000;
let iteraction = 0;


this.stringResourcesService.getStringResourcesInProject(projectId, false, false, false, 0, batchSize)
  .pipe(
    expand(partialData => {
      if (partialData) {
        let partialStringResourcesInProject = partialData as StringResource[];

        if (partialStringResourcesInProject.length > batchSize) {

          // Loads the remaining rows in the Grid
          this.gridApi.updateRowData({ add: partialStringResourcesInProject });

          iteraction += 1;

          return this.stringResourcesService.getStringResourcesInProject(projectId, false, false, false,
                       batchSize * (iteraction - 1), batchSize);
        }

        return EMPTY;
      }
    })
  ).subscribe(data => {

        //... 
  },
  error => of(null),
  () => {
    this.agGridService.refreshSizeColumns(this.agGrid);
  });
...