2017-12-03 7 views
0

Observables 및 Reactive Programming rxjs를 처음 사용하기 때문에 redux-observable 라이브러리를 react/redux 응용 프로그램에 추가했습니다.startWith operator Rxjs가 예상대로 작동하지 않습니다.

LOGIN_REQUEST 동작이 실행되면 로그인 작업을위한 서사시를 만들었습니다. 기본적으로 LOGIN_REQUEST 동작이 실행되면 먼저 작업을 실행하는 동안 사용자에게 회전 휠을 표시하기 위해 SET_LOADING 동작을 시작합니다. done을 실행 한 다음 서버를 요청하여 사용자를 가져옵니다.

const loginEpic = (action$) => { 
    console.log('EPIC LOGIN EXECUTED'); 
    return action$.filter(action => action.type === LOGIN_REQUEST) 
     .mergeMap(action => ajax.post(getUrl(constants.LOGIN), 
      action.payload)) 
     .map(response => setUser(response.response)) 
     .takeUntil(action$.ofType(LOGIN_REQUEST_CANCELLED)); 
     .startWith(setLoading(true)); 
}; 

나는 즉시 LOGIN_REQUEST 해고 된 SET_LOADING 조치를 (이것은 내가 기대하는 행동입니다) 시작 운영자 startWith을 사용하고 있습니다 :

이 내가 쓴 코드입니다. 그러나 이전 LOGIN_REQUEST 작업조차없이 응용 프로그램을 처음로드 할 때 SET_LOADING 동작이 시작되는 이유를 알 수 없습니다.

제가 제거하면 SET_LOADING 동작이 시작되지 않기 때문에 문제가 startWith 연산자와 관련되어 있다는 것을 알고 있습니다. 그래서 내가 뭘 잘못하고 있니? 이 SET_LOADING 동작이 LOGIN_REQUEST 동작 후에 항상 발생하는 이유는 무엇입니까?

감사

+0

나는 당신이 .startWith 연산자가 무엇을 오해 할 수있다 생각합니다. http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html 예제에서 setLoading (true)이 즉시 호출되고 반환 값이 관찰 가능한 스트림으로 이동합니다 – wywong

답변

3

에픽 그냥 관찰하고 그것이 파견하는 행동을 생성 할 때마다. startWith를 다음과 같이 사용하면 구독을 시작할 사람이 즉시 setLoadingAction을 수신하게됩니다. 대신 필터가 true 인 경우에만 loadingAction을 발생시켜야합니다. 이 라인을 따라

뭔가 :

const loginEpic = (action$) => { 
    console.log('EPIC LOGIN EXECUTED'); 
    return action$.filter(action => action.type === LOGIN_REQUEST) 
     .mergeMap(action => Observable.merge(
       Observable.of(setLoading(true)), 
       Observable.fromPromise(ajax.post(getUrl(constants.LOGIN), 
        action.payload)) 
     .map(response => setUser(response.response)) 
     .takeUntil(action$.ofType(LOGIN_REQUEST_CANCELLED))); 
};