用前钩和后钩拦截每个请求

问题描述 投票:1回答:1

我必须向5个不同的端点发出5个请求(顺序无关紧要)。这些端点的URL除业务线外均相同。这些业务线是from的数组。

我想在每个请求之前显示一个骨架加载器,并在完成后隐藏。因此,基本上流程是:

1. [Hook - before request]
2. [Log of data fetched]
3. [Hook - after request]

这是我的服务:

export function getInsurances(
    userIdentity: string,
    hooks?: RequestHooks
): Observable<Policy[]> {
    return from(["all", "vehicle", "health", "soat", "plans"]).pipe(
        tap(() => hooks?.beforeRequest && hooks.beforeRequest()),
        flatMap<string, Observable<Policy[]>>(businessLine => {
            return InsurancesApi.getPolicies<Policy>(
                userIdentity,
                businessLine
            ).pipe(
                map(policies => {
                    return policies.map(policy => PolicyStandarizer(policy));
                }),
                finalize(() => {
                    hooks?.afterRequest && hooks.afterRequest();
                })
            );
        }),
        catchError(err => of(err)),
        takeUntil(HttpCancelator)
    );
}

这是我的订阅:

const hooks = {
    beforeRequest() {
        Log.info("Before Request");
        setStatus(HttpRequestStatus.PENDING);
    },
    afterRequest() {
        Log.warn("After Request");
        setStatus(HttpRequestStatus.RESOLVED);
    },
};
getInsurances(userIdentity, hooks).subscribe(
    policies => {
        Log.normal("Policies:", policies);
        setInsurances(policies);
    },
    (err: Error) => {
        setError(err);
    }
);

并且有此输出(对不起,粘贴链接,我无法嵌入图像,因为代表):

https://i.stack.imgur.com/Nbq49.png

finalize运行正常,但tap一次执行了五次。

谢谢。

ajax rxjs observable rxjs6
1个回答
1
投票

我认为您会收到此行为,因为from会同步发出项目,因此它与执行操作基本相同:

for (let i = 0; i < arr.length; i++) {
  console.log('before req');

  observer.next(arr[i]);
}

observer.complete();

[afterRequest正确显示,因为涉及的动作是异步的。

如果只触发一次该事件,则在所有请求被触发之前,您可以尝试以下操作:

from([...])
  .pipe(
    finalize(() => hooks?.beforeRequest && hooks.beforeRequest()),
    flatMap(/* ... */)
  )

编辑-在每个请求之前记录事件

flatMap(
  value => concat(
    of(null).pipe(
      tap(() => hooks?.beforeRequest && hooks.beforeRequest()),
      ignoreElements(), // Not interested in this observable's values
    ),
    InsurancesApi.getPolicies(/* ... */)
  )
)
© www.soinside.com 2019 - 2024. All rights reserved.