我必须向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
一次执行了五次。
谢谢。
我认为您会收到此行为,因为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(/* ... */)
)
)