У меня есть компонент мастера Angular, содержащий 2 шага. На первом этапе форма показывается пользователю. На втором шаге другая форма отображается в результате продолжительного HTTP GET. В настоящее время это работает, когда пользователь прибывает на второй шаг, выполняется запрос, и в конечном итоге пользователь видит форму как результат продолжительного вызова; однако пользователю досадно ждать окончания запроса.
Чтобы оптимизировать, я пытаюсь запустить длительный запрос на первом шаге мастера в фоновом режиме , чтобы сократить время ожидания для пользователя. Технически это возможно, потому что параметры запроса не зависят от действий пользователя на шаге 1.
Однако трудность состоит в том, что Observables ничего не делают, если вы не подписаны на них. Но когда я подписываюсь на наблюдаемый запрос, на шаге 1 мастера он будет ждать его завершения (таким образом, для пользователя не будет никакого повышения производительности).
Так что мне нужно как-то подписаться на наблюдаемый запрос, но в фоновом режиме, который не блокирует конвейер begin .
Каждый шаг мастера имеет onStepBegin
и onStepFinish
. На шаге 1 onStepBegin
я хочу немедленно создать наблюдаемое и выполнить запрос. Затем на шаге 2 onStepBegin
следует дождаться оставшегося времени запроса.
Технически код, приведенный ниже, работает, но запрос запускается не ранее, чем на шаге 2. Как я могу заставить его немедленно запустить запрос на шаге 1?
Я попробовал следующие вещи чтобы исправить это:
- Добавьте оператор publi sh, чтобы сделать наблюдаемое горячим: не помогает, так как оно станет горячим после подписка
- Подписаться с ручным
subscribe()
вызовом; но так называемые вложенные подписки создают утечки памяти
Мастер шаг 1:
public onStepBegin(begin: Observable<any>): Observable<MyContext> {
return begin.pipe(
tap(() => {
..
this.context.loadInitial = this.loadInitialConfigurations(this.selectedElementclass.id).pipe(
first(),
publish()
);
})
);
}
Мастер шаг 2:
public onStepBegin(begin: Observable<any>): Observable<MyContext> {
return begin.pipe(
switchMap(() => this.context.loadInitial),
tap((c) => {
this.context.configurations = c;
}),
);