Angular Rxjs Множественные параллельные HTTP-запросы/вызовы, блокирующие навигацию - приоритетная отмена очереди одновременно

Я знаю, что есть похожие темы, но нет ни одной, которая дала бы подходящее решение для моей проблемы.

Pre: Я перемещаюсь на стороне сервера и на стороне клиента одновременно. Это означает, что каждая навигация во внешнем интерфейсе с помощью routerLink и любого вызываемого маршрута сопровождается вызовом HTTP-запроса на сервер.

Ситуация: я открываю диалоговое окно, чтобы показать форму для создания файла position. Для этого position мне нужно показать список elements, которые я загружаю из API. Для каждого element мне нужно загрузить дополнительный thumbnail. Поэтому мне нужен один вызов API, чтобы получить 86 elements, а затем 86 запросов, чтобы получить thumbnail. Я сохраняю эти элементы в службе, чтобы предотвратить их повторную загрузку. Поэтому я проверяю, есть ли уже elements, прежде чем загружать их. Вызовы API запускаются, когда я открываю диалог.

getElementsWithThumbnails() {
    if (this.elementsSource.value.length === 0) {
        this.apiService.getElements().subscribe(
            (next) => {
                this.elementsSource.next(next);
                this.elementsSource.value.forEach((epl, index) => {
                    const format = 'JPG';
                    this.apiService.getThumbnail(epl.id, format, '400', '400', 'true').subscribe(
                        (blob) => {
                            epl.thumbnail = blob;
                        }
                    );
                });
            }
        );
    }
}

ThumbnailRequestMethod:

getThumbnail(
    elementId: string, format: string, width: string,
    height: string, sameratio: string
): Observable<SafeUrl> {
    return this.httpClient.get(
        this.apiUrl +
        `/elements/${elementId}/thumbnail?format=${format}&width=${width}&height=${height}&sameratio=${sameratio}`
        , {
            responseType: 'blob'
        }).pipe(
        map(res => {
            return this.blobToSanitizedUrl(res);
        })
    );
}

Проблема: если пользователь решает отменить форму и хочет перейти вперед/назад - он не может, потому что navigation request находится в конце очереди.

Есть ли какой-либо метод, который устанавливает приоритет вызовов thumbnail для более низкого уровня, который будет обрабатываться при меньшей нагрузке?

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


person liqSTAR    schedule 19.08.2019    source источник


Ответы (1)


Проблема в том, что у браузера есть ограничение на параллельные запросы к одной и той же конечной точке. Является ли API тем же источником, что и интерфейс? Если это не предел, вероятно, ниже.

На мой взгляд:

  1. Используйте URL-адреса для миниатюр. Я предполагаю, что вы отображаете их в некоторых тегах img. Почему бы не установить href и позволить браузеру обрабатывать загрузку изображений. Развивая эту идею, вы можете использовать директиву «inview», чтобы отложить загрузку изображений до тех пор, пока они не появятся в поле зрения (это также зависит от бизнеса и требований).

  2. Ограничьте количество параллельных запросов до getThumbnail. Вы можете сделать это так (используя параметр concurrent для mergeMap):

const format = 'JPG';
this.apiService.getElements()
  .pipe(
    switchMap(items => {
      this.elementsSource.next(items);
      return from(items);
    }),
    mergeMap(item => {
      return this.apiService
        .getThumbnail(item.id, format, '400', '400', 'true')
        .pipe(
          tap(blob => item.thumbnail = blob)
        )
    }, 2) // max 2 requests in parallel
  )
  .subscribe();
person Andrei Tătar    schedule 19.08.2019
comment
1. Невозможно в этом случае использования, потому что изображения находятся на файловом накопителе. 2. работает как шарм, в слиянии отсутствует return, но все остальное в порядке.. - person liqSTAR; 20.08.2019
comment
@liqSTAR ах да, кажется, я сначала хотел без фигурных скобок :) - person Andrei Tătar; 20.08.2019