Angular 2 - Избегайте задержки при связывании HTTP-запроса

    this.http.get(validate\uniqueness).subscribe(unique => {
        console.log(" first subscribe ");
        if(unique.isValid) {
            this.http.put(url, data).subscribe(val => {
            console.log("second Subscribe")
            }
        });
    });

У нас есть настраиваемый HTTP-счетчик, который запускается, когда запрос находится в режиме ожидания, и останавливается, когда получен ответ. В приведенном выше коде при первом вызове подписки вызывается счетчик, и счетчик останавливается, как только будет получен результат и страница отображается без счетчика, а при повторном вызове второй подписки снова вызывается счетчик. У нас может быть некоторая задержка между первым и вторым звонками .. Есть ли способ избежать задержки? Я использовал mergeMap, flatMap, но безуспешно.


person user2810022    schedule 26.07.2017    source источник


Ответы (1)


Прежде всего, вы должны связать свои http звонки:

this.http.get(validate\uniqueness)
    .map(req => req.json().unique)
    .filter(unique => unique.isValid)
    .switchMap(this.http.put(....))
    .subscribe(val => console.log(val))

Но это тоже не решит твою проблему. Здесь у вас есть два отдельных http запроса, один из которых инициируется другим. Между этими запросами всегда будет некоторая задержка. Вероятно, вы можете добавить задержку перед остановкой счетчика, позволяя последующим запросам «ездить» на том же счетчике.

Что я сделал для индикации загрузки, так это написал свой rxjs operators.

По сути, мои http-вызовы выглядят так:

Observable.loadingDefer('name of loading state', () => {
    // log or whatever
    return this.http.get(...)
})
.map(...)
...
.stopLoading('name of loading state')
.subscribe(...)

У меня есть простая служба, которая сохраняет Map<string, BehaviourSubject<boolean>>, который в основном представляет собой карту между именем состояния загрузки (в случае, если я хочу воздействовать на разные объекты и не иметь одного глобального состояния загрузки), и субъектом поведения, который указывает, является ли это загрузка или нет, по умолчанию false.

Observable.loadingDefer использует Observable.defer, за исключением того, что он использует службу (которая экспортируется как своего рода синглтон, как и angular-redux's NgRedux) и указывает состояние загрузки.

Оператор stopLoading использует оператор finally для отправки знака остановки для индикации. Я использовал здесь finally для рассмотрения случаев, когда запросы не выполняются.

Для меня это достаточно хорошо, но я предполагаю, что он создает некоторый шаблон для каждого вызова http. Возможно, этого можно избежать.

Надеюсь, это вам как-то поможет :)

person Giora Guttsait    schedule 26.07.2017
comment
Спасибо за ваше предложение, явно срабатывает счетчик, чтобы избежать задержки - person user2810022; 03.08.2017
comment
Не могли бы вы отметить ответ буквой V? Спасибо :) Рад помочь! - person Giora Guttsait; 05.08.2017