redux saga eventChannel에 관하여

2020. 7. 29. 16:43Dev

반응형

saga의 eventChannel을 이용하여 pusher의 구독을 감지해 redux action을 실행해주는 로직

문제는 특정 action으로 인해서 지속적으로 pusher 구독을 실행하는 상황이 발생해 이벤트 바인딩이 계속해서 증가하는 현상이 발생한다는 것.

 

function* sagaLogic() {
	:
	const channel = eventChannel((emitter) => {
		const pusherChannel = pusher.subscribe(pusherKey);
		pusherChannel.bind(event, (enc) => {
        	emitter(enc)
		});
 	})

	while (true) {
		const enc = yield take(channel);
		:
	}
}

export default function* sagas() {
	takeLatest(ACTION, sagaLogic),
}

처음에는 구독 중임을 감지해서 감지 중일경우에는 해당 로직에 진입하지 못하도록 적용하면 해결 될거라 생각.

하지만 이상하게도 해당 로직을 적용 한 후 channel을 더 이상 take 하지 못하는 현상이 발생했다.

 

분석해보니 진짜 문제는 해당 제네레이터를 실행하는 saga 로직이 takeLatest 였다는 점에 있었다. takeLatest(ACTION, sagaLogic) 으로 감지할 경우 ACTION이 실행되면서 이전에 실행하던 제네레이터(sagaLogic)를 종료 시켜 버린다. 따라서 eventChannel 또한 강제로 종료되고 더이상 emitter 실행을 감지할 수 없었다.

 

takeLatest를 takeEvery로 변경해주면 해결되는 문제(물론 구독 감지 판단도 필요)

아니면 sagaLogic 제네레이터 안에서 별도로 spawn을 사용해 별도의 컨텍스트로 분리해서 사용해도 될 것으로 보인다.

 

제네레이터가 실행되는 시점과 컨텍스트 유지 측면을 생각하면서 설계하지 않는다면 버그가 발생하기 좋다.

제네레이터가 직관적이지 않기 때문에 사용하지 말자는 말도 이해가 간다.

하지만 이해도가 높아지면 간결한 코드를 효율적으로 작성하기 때문에 도전해볼만 하다.

반응형

'Dev' 카테고리의 다른 글

Next.js i18n  (0) 2021.05.29
amplify nextjs ssr  (0) 2021.05.02
drag and drop(feat. react)  (0) 2020.02.14
web resource hint  (0) 2020.01.02
re-render에 너무 목매지 말자  (0) 2019.10.01