Корень моей проблемы заключается в отображении индикатора загрузки на http-запросах, и я хочу сделать это на уровне службы без необходимости писать код для каждого компонента. Что я сделал, так это реализовал http-оболочку, которая в основном делает это:
getMyHttpObservable(...) {
setLoadingIndicator(true);
const myHttpObservable =
createRequestObservable().finally(()=> {
console.log('http done');
setLoadingIndicator(false);
});
return myHttpObservable;
}
У меня есть последовательность наблюдаемых, которые я связываю с помощью Observable.concat
следующим образом:
const t1 = Observable.timer(5000).finally(()=>console.log('t1 done'));
const t2 = getMyHttpObservable(...);
const agg = Observable.concat(t1,t2);
Я использую метод отмены на основе событий, используя Observable.takeUntil
следующим образом:
const ev = new EventEmitter<any>();
const cancellableAgg = agg.takeUntil(ev.asObservable());
Теперь проблема в том, что когда я отменяю агрегатное наблюдаемое в течение первого периода таймера, я не получаю окончательный вызов второго наблюдаемого - http-запрос. Пример:
const cancel = Observable.timer(500).finally(()=>ev.emit());
cancellableAgg.subscribe();
cancel.subscribe();
Когда вышеприведенное выполняется, я получаю этот вывод:
t1 done
И мне нужно получить еще и http done
, чтобы индикатор загрузки был очищен. Как я могу этого добиться?
Спасибо!
ИЗМЕНИТЬ
Я не понял, что оператор concat
подписывается на наблюдаемые только после завершения их предшественников. Что мне нужно, так это активировать мой индикатор загрузки только тогда, когда наблюдаемый http действительно подписан.
Я изменил свою функцию-оболочку следующим образом:
getMyHttpObservable(...) {
const myHttpObservable = createRequestObservable(...);
const subscriptionAware = new Observable(subscriber => {
setLoadingIndicator(true);
myHttpObservable.subscribe(
nextEv => subscriber.next(nextEv),
errEv => subscriber.error(errEv),
() => subscriber.complete())
.add(()=>setLoadingIndicator(false));
};
return subscriptionAware;
}
Итак, в основном я создаю Observable
, который прозрачно оборачивает другой Observable
, но также выполняет некоторые дополнительные действия, когда он действительно подписан - активирует индикатор загрузки.
Однако теперь я потерял возможность отменять запросы XHR в полете, поскольку конструктор Observable
не позволяет мне передать обработчик отмены, поэтому внутренняя подписка никогда не будет отменена.
Любые идеи о том, как этого добиться?