【问题标题】:Angular Rxjs Multiple Parallel HTTP Requests / Calls blocking navigation - Priority Cancel Queue ConcurrentAngular Rxjs 多个并行 HTTP 请求/调用阻塞导航 - 优先取消队列并发
【发布时间】:2019-08-19 06:05:56
【问题描述】:

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

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

情况:我正在打开一个对话框以显示一个创建position 的表单。对于这个position,我需要显示我从API 加载的elements 列表。对于每个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 调用的优先级设置在较低的调用上以在较小的负载上进行处理?

提前致谢。

【问题讨论】:

    标签: angular typescript rxjs httprequest switchmap


    【解决方案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();
    

    【讨论】:

    • 1.在此用例中不可能,因为图像位于文件驱动器上。 2. 像魅力一样工作,mergeMap 中缺少return,但其他一切正常..
    • @liqSTAR 啊,是的,我想我一开始希望它不带花括号:)
    猜你喜欢
    • 1970-01-01
    • 2022-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    相关资源
    最近更新 更多