angular http-перехватчик - прервать ответ

Есть ли способ использовать http-перехватчики angular для перехвата ответа и как бы удалить его / выбросить, чтобы будущие обратные вызовы нисходящего потока не выполнялись?

Я хочу, чтобы он вел себя так, чтобы ни один из console.log не запускался.

this.http.get('/foo').subscribe(
    data => console.log("success", data),
    err => console.log("fail.", err)
);

Я видел примеры, которые изменяют ответ или заменяют ответ нулевым или другим сигнальным значением, но я бы предпочел не делать этого, потому что тогда все мои обработчики успеха / неудачи должны искать дозорного, что снижает полезность использование перехватчика для обработки определенных ответов.

У меня такое чувство, что это скорее вопрос rxjs, чем вопрос перехватчика angular, но я просто еще недостаточно знаком с rx, чтобы быть уверенным.

Если это важно, я использую angular 5.1


person goat    schedule 14.02.2018    source источник
comment
Описание перехватчика: Перехватывает HttpRequest и обрабатывает их. Я не уверен, можно ли использовать HttpInterceptor для перехвата ответа.   -  person Harry Ninh    schedule 15.02.2018
comment
@HarryNinh это возможно - обратите внимание, я сказал, что видел примеры, которые изменяют ответ   -  person goat    schedule 15.02.2018
comment
Поможет ли вам положить в перехватчик что-то вроде return next.handle(req).switchMap(() => Observable.empty());?   -  person Harry Ninh    schedule 15.02.2018
comment
Привет, @goat, может быть, это поможет вам: stackoverflow.com/questions/45566944/   -  person Narm    schedule 15.02.2018
comment
@HarryNinh, спасибо, это сработало :) если вы опубликуете его как ответ, я приму его, так как он ответил на вопрос, который я задал. К сожалению, для простоты я не включил тот факт, что я использую get(...).toPromise().then(...) вместо subscribe(...), и кажется, что toPromise изменяет поведение и приведет к разрешению обещания с неопределенным аргументом. Есть идеи, как это обойти (например, чтобы он не разрешился)? Может мне стоит задать это как новый вопрос.   -  person goat    schedule 16.02.2018


Ответы (2)


Вы можете использовать Observable.empty для завершения потока без передачи каких-либо данных. Чтобы объединить его с HttpInterceptor, свяжите его с next.handle:

return next.handle(req).switchMap(() => Observable.empty());

Я не знаю, как это сделать с Promise, извините.

person Harry Ninh    schedule 17.02.2018

Я нашел еще один метод, который предотвратит вызов обратных вызовов subscribe (). Вот пример перехватчика, который будет воздерживаться от вызова нижестоящих подписчиков, если в HttpResponse присутствует определенный HTTP-заголовок.

Однако имейте в виду, что этот метод на самом деле не «отбрасывает ответ». Вместо этого ответ откладывается на неопределенное время. Если у вас есть код, который использует таймеры (например, какой-то код, который выдаст ошибку, если в течение 60 секунд не будет получен ни успешный, ни ошибочный ответ), это может быть проблемой, потому что именно так работает этот метод - он просто никогда не отвечает.

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(req).pipe(
        switchMap((event: HttpEvent<any>) => {

            // In this example, I only care about checking valid http responses.
            // But, if you also want to inspect errors, you might consider checking for HttpResponseBase or HttpErrorResponse
            if (event instanceof HttpResponse) {

                // Check if this response has a certain http response header set.
                // If so, we throw the response away.
                if (event.headers.has('my-custom-header')) {
                    // We intentionally return an Observable that will never complete. This way,
                    // downstream subscribers will never receive anything, and any .toPromise()
                    // conversions that may be present will also never be invoked because toPromise() only
                    // gets invoked when the Observable completes.
                    // It doesn't actually throw the response away, but rather, it makes the subscribers wait forever, so they will never get a response.
                    // Be careful if you use timeouts.
                    return new Subject<HttpEvent<any>>();
                }

            }

            // The default case - we pass the response back through unmodified.
            return Observable.of(event);
        })
    );
}

// These console.logs will not be called
this.http.get('/foo').subscribe(
    data => console.log("success", data),
    err => console.log("fail.", err)
);

// Neither will these
this.http.get('/foo').toPromise(
    data => console.log("success", data),
    err => console.log("fail.", err)
);
person goat    schedule 15.02.2019