Я пытаюсь составить цепочку наблюдаемых в приложении Angular и пытаюсь найти порядок операций, чтобы заставить его работать по мере необходимости.Любые идеи / указания о том, как реализовать это, будут наиболее цениться.
Меня особенно интересует правильная последовательность операторов, чтобы существующая структура кода работала в нужном порядке, без обширного рефакторинга.
Вот что я пытаюсь достичь (в описании, затем псевдокод, затем упрощенная версия моего кода, поскольку он распространяется на несколько служб):
description
Каждый из следующих шагов является наблюдаемым, причем первым является точка, где вызывается subscribe()
.
1: при успешном входе в систему инициализировать службу пользователя.Это наблюдаемая, которая подписывается сразу.
2: Внутри этой инициализации проверьте, не устарел ли контент: извлеките удаленный JSON-файл и сравните его значение с тем, которое хранится локально.Если они различаются (содержимое устарело), очистите кэш содержимого.
3: После проверки содержимого вызовите две дополнительные службы для получения файлов JSON - сначала путем поиска их в кэше, а затем путем выборки с удаленного сервера.
Порядок важен между шагами 2 и 3 - шаг 2 должен быть выполнен до начала шага 3.Заказ не имеет значения для вызовов службы на шаге 3.
Если бы я регистрировал каждый шаг, я хотел бы видеть что-то вроде этого, если контент устарел:
logon success, initializing user
content is stale, flushing cached content
flushing cached content complete
fetching content
fetching domain
domain fetch complete
content fetch complete
и если контентне устарел:
logon success, initializing user
content is not stale
fetching content
fetching domain
content fetch complete
domain fetch complete
псевдокод
logon
on success, (initialize user with logon response)$.subscribe()
(initialize user with logon response)$
// other stuff happens ...
return (fetch remote file and act on content)$
then
(get content file foo)$, (get content file bar)$
(fetch remote file and act on content)$
if content is stale
return (flush cached content)$
else
return (empty observable)$
(get content file xxx)$
if file is in cache
return (retrieve file from cache)$
else
return (fetch remote file)$
упрощенный код
// login-view.component.ts
loginClick() {
this.logonUserService
.logon(credentials)
.subscribe((logonResponse) => this.userService.initialize(logonResponse).subscribe());
}
// user.service.ts
initialize(logonResponse) {
// do stuff with logonResponse, then...
return this.checkContentFreshnessService.initialize()
.pipe(switchMap(() => forkJoin(
this.contentService.initialize(),
this.domainService.initialize()
));
}
// check-content-freshness.service.ts
initialize(): Observable<any> {
return this.contentService.getPublishSummary().pipe(
tap(
publishSummary => {
const isContentStale = publishSummary.changesetId === this.contentService.changesetId;
return iif(
() => isContentStale,
this.contentService.flushCache(),
of(true)
);
}
)
);
}
// content.service.ts & domain.service.ts are both essentially
initialize(): Observable<any> {
const path = this.contentService.getContentPath(contentId);
// or: const path = this.contentService.getDomainPath();
return this.contentService.get(path).pipe(
tap(response => { /* do something locally with response */ }
);
}