2017-11-20 10 views
0

다음 코드가 작동합니다. 그것은 아약스 요청을 수행하고 다음 번에이 작업을 호출TypeError : 스트림이 예상되는 곳에 잘못된 개체를 입력했습니다.

export const loadThingsEpic = action$ => { 

    return action$.ofType(LOAD_THINGS) 
    .mergeMap(({things}) => { 
     const requestURL = `${AppConfig.serverUrl()}/data/things`; 
     return ajax.getJSON(requestURL)).map(response => { 
     return finishLoadingThings(response); 
     }).map(() => { 
     return sendNotification('success'); 
     }); 
    }) 
    .catch(e => { 
     return concat(of(finishLoadingThings({ things: {} })), 
        of(sendNotification('error'))); 

    }); 
}} 

하지만이 코드는하지 않습니다

export const loadThingsEpic = action$ => { 

    return action$.ofType(LOAD_THINGS) 
    .mergeMap(({things}) => { 
     const requestURL = `${AppConfig.serverUrl()}/data/things`; 
     return ajax.getJSON(requestURL).switchMap(response => { 
     return concat(of(finishLoadingThings(response)), 
         of(sendNotification('success'))); 
     }); 
    }) 
    .catch(e => { 
     return concat(of(finishLoadingThings({ things: {} })), 
        of(sendNotification('error'))); 
    }); 
} 

내가 함께이 작업을 병합하는 switchMap에 의해지도를 교체했습니다 (다른 많은 게시물에서 볼 수 있듯이). 예외가 발생하면 catch에서 작동합니다. 코드에 무슨 문제가 있는지 궁금합니다. Map, swicthMap 및 mergeMap과 같은 사용시기를 실제로 파악할 수 없기 때문에 추측하고 있습니다.

sendNotification에와 finishLoadingthings 반환 조치 개체 :

export function finishLoadingThings(data: any) { 
    return { 
    type: FINISH_LOADING_THINGS, 
    data, 
    }; 
} 

감사합니다!

+0

그냥 첫 번째 코드가 작동하는 것처럼 보였지만 첫 번째 작업은 감속기에 의해 수신되지 않습니다 ... 저는 매우 혼란 스럽습니다 ... – ThePainnn

+0

제가 도울 수 있다고 생각합니다. 예제를 간소화하거나 사용되는 다양한 함수의 정의를 제공 할 수 있습니까? 그들 모두가 무엇을하고 돌아 왔는지 분명히하고 싶습니다. – jayphelps

+0

예제를 단순화했습니다. 감사! – ThePainnn

답변

1

제공된대로 코드가 의도 한대로 작동하는 것으로 보입니다. https://jsbin.com/becapin/edit?js,console ajax가 성공하거나 실패 할 때 "스트림이 예상되는 곳에 유효하지 않은 개체"오류가 표시되지 않습니다.

오류가이 코드에서 발생 했습니까?

별도의 노트에

, 당신은 Observable.of 인수 개수를 임의로 설정할 수 있습니다 듣고 행복 할 수도, 각각은 다른 후 방출됩니다. 그래서 대신의 :

.switchMap(response => { 
    return concat(of(finishLoadingThings(response)), 
       of(sendNotification('success'))); 
}); 

당신은이 작업을 수행 할 수 있습니다

이 비록 버그가 발생하지 않았을
.switchMap(response => { 
    return of(
    finishLoadingThings(response), 
    sendNotification('success') 
); 
}); 

, 그냥 청소기입니다.

+0

내 서사시를 정리 한 후, 그것은 밖으로 상자에서 작동하는 것. 팁 주셔서 감사합니다, 이것은 정말로 도움이됩니다! RxJS는 시작하기가 약간 어렵지만 앱이 커지면 성과가 올 것이라고 생각합니다. – ThePainnn

0

나는 mergeMap과 같은 레벨에서 switchMap을 수행하여 문제를 해결할 수있다. 이와 같이 :

export const loadThingsEpic = action$ => { 

    return action$.ofType(LOAD_THINGS) 
    .mergeMap(({things}) => { 
     const requestURL = `${AppConfig.serverUrl()}/data/things`; 
     return ajax.getJSON(requestURL).switchMap(response => { 
     return of(response); 
     }); 
    }) 
    .switchMap((res) => { 
     return concat(of(finishLoadingThings(res.value)), 
         of(sendNotification('success'))); 
    }) 
    .catch(e => { 
     return concat(of(finishLoadingThings({ things: {} })), 
        of(sendNotification('error'))); 
    }); 
} 

아직 얻지 못했습니다.

+0

최상위에 캐치를 배치하는 것은 mergeMap 내부와 동일하지 않습니다. 그것은 당신이 그 행동을 원하지 않을 가능성이 매우 높습니다 - 서사시는 오류가있을 때 미래의'LOAD_THINGS'를 듣지 않습니다. – jayphelps

+0

예. 나는 그것을 알아 차렸다. 최상위 수준에서 takeUntil과 동일한 작업을 수행합니다. 액션 유형이 서사시를 받으면 바로 중지합니다. – ThePainnn

+0

Observable chain이 실제로 어떻게 작동하는지 더 자세히 알아 보려면 더 자세히 이해하십시오. 일단 당신이하면 당신은 정말로 레벨 업 될 것입니다 : https://medium.com/@benlesh/learning-observable-by-building-observable-d5da57405d87 – jayphelps