2017-03-27 13 views
2

약속을 사용하면 오류가 발생했을 때 .then 변종을 사용하여 체인을 분할 할 수 있습니다. 다음은이 날 응답 처리 논리를 건너 뛰고은 원래 가져 오기 문에서 제기 된 오류에 응답 할 수 fetchRxJS에서 오류가 발생했을 때 분할 관찰 가능

fetch('http://website.com').then(
    // Perform some logic 
    (response) => response.json().then(({ answer }) => `Your answer: ${answer}`), 
    // Skip json parsing when an error occurs 
    (error) => 'An error occurred :(', 
).then(console.log); 

를 사용하는 예입니다. RxJS 비슷한 뭔가 다음과 같습니다 코드 상태의 주석, 나는 단순히 내 약속 체인과 같은 동작을하지 않는 한에서 캐치 연산자를 넣을 수 없습니다

Observable.fromPromise(fetch('http://website.com')) 
    // if I put .catch here, the result will be piped into flatMap and map 
    .flatMap(response => response.json()) 
    .map(({ answer }) => `Your answer: ${answer}`) 
    // if I put .catch here, errors thrown in flatMap and map will also be caught 
    .subscribe(console.log); 

으로.

나는 이것을 실현시킬 수있는 커스텀 연산자를 사용하거나 이것을 관찰 할 수있는 오류를 병합 할 수 있다는 것을 알고있다. 그러나 모든 것은 꽤 과장된 것 같다. 약속 체인 작동을 달성하는 간단한 방법이 있습니까?

답변

6

실제로 내가 귀하의 상황에 있다면 나는 flatMapmap에서 오류를 잡는 것에 대해 걱정하지 않을 것입니다. Observable 소스가 오류를 던지면 관찰자에게 전달됩니다. 호출 할 때 그래서 난 그냥 (그렇지 않으면 오류가 던져 준다) 가입 오류 처리기를 사용하십시오 :

.subscribe(console.log, err => console.log('error:', err)); 

오류가 (귀하의 경우 약속) 관찰 가능한 소스에서 발생 때 error 알림으로 전달 있다는 것을 참고 표준이 아닌 next 알림입니다. 즉, flatMap()map()은 오류 메시지에 아무런 영향을 미치지 않습니다. catch() 또는 materialize()을 사용하면 두 연산자 (flatMapmap)가이 유형의 데이터를 처리 할 수 ​​있어야하며 (다른 오류는 던지지 않음).

어쨌든 당신은 항상 share() 또는 publish()를 사용하여 각 신호의 한 종류 처리하는 경우 두 개의 서로 다른 구독 할 수 있습니다 :

let source = Observable.fromPromise(fetch('http://website.com')).publish(); 

source 
    .subscribe(undefined, err => console.log(err)); 

source 
    .flatMap(...) 
    .map(...) 
    .subscribe(console.log,() => {}); 

source.connect(); 

지금 난 단지 오류에 대해 별도의 관찰자가 있습니다.

() => {}으로 빈 콜백을 만들어야한다는 점에 유의하십시오. 오류는 자동으로 무시됩니다. 또한 멀티 캐스팅 (publish() 연산자)을 사용할 때 Subject 내부에는 내가 알고 있어야하는 특정 동작이있을 수 있지만 사용 케이스에서는 중요하지 않을 수 있습니다.

+0

두 가지 종류의 오류를 구분하려는 이유는 합리적으로 복구 할 수 있거나 '가져 오기'오류 (예 : 네트워크에 문제가 있음)에서 어떤 종류의 피드백을 줄 수 있기 때문입니다. flatMap 또는 map에서 오류가 발생하면 내 자신의 오류 일 가능성이 높습니다. 따라서 오류가 구독자에게 전파되기를 바랍니다. – Pinpickle

+0

당신의 솔루션이 마음에 들지만, 제 목표는 결과 (이 경우 오류 또는 json을 파싱하는 문자열)를 동일한 관찰 가능 부분에 포함시키는 것입니다. 둘을 병합하는 것이 좋습니다. – Pinpickle

+1

'Observable.fromPromise()'바로 다음에'catch()'를 사용하고 자체 오류 클래스 ('catch()')로 오류를 래핑했을 때보 다 자신의 오류 클래스로 오류를'오류 '신호). 나중에 관찰자에서 오류가 typeof인지 또는 특정 클래스를 구현하는지 확인할 수 있습니다. 이것은 오류가'fromPromise'에서 발생했는지와'catch()'또는 예를 들어서 잡혔는지 확인할 수 있음을 의미합니다. 'map'은 일반적인 오류입니다. 어쩌면 오류를 잡는 'retryWhen()'연산자를 살펴보고 나만의 알림을 기반으로 자동으로 다시 가입 해 봅시다. – martin

관련 문제