0

我知道有类似的线程,但没有一个为我的问题提供合适的解决方案。

Pre: 我在服务器端和客户端同时导航。这意味着使用 routerLink 和任何被调用的路由在前端的每个导航都伴随着对服务器的 HTTP 请求调用。

情况:我正在打开一个对话框来显示一个表单来创建一个position. 为此,position我需要显示elements我从 API 加载的列表。对于每个element我需要加载一个额外的thumbnail. 所以我需要一个 API 调用来获取 86 elements,然后是 86 请求来获取thumbnails。我将这些元素保存在服务中以防止再次加载它们。因此,我在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;
                        }
                    );
                });
            }
        );
    }
}

缩略图请求方法:

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呼叫优先级设置为在较小的负载上处理?

提前致谢。

4

1 回答 1

1

问题是浏览器对同一端点的并行请求有限制。api与前端是否同源?如果不是这个限制可能会更低。

我的看法:

  1. 使用 url 作为缩略图。我假设您在某些img标签中显示它们。为什么不设置href并让浏览器处理图像的加载。继续这个想法,您可以使用“inview”指令来延迟图像的加载,直到它们实际在视图中(这也取决于业务和要求)。

  2. 将并行请求限制为getThumbnail. 你可以这样做(使用concurrentmergeMap的参数):

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();
于 2019-08-19T07:08:24.907 回答