React

redux-saga method(delay, call, put, fork, all, takeEvery, takeLatest)

# 시작

Nextjs로 Redux를 사용하면서 Redux-saga를 처음 적용해보게 되었다. yield와 Generator를 사용해서 비동기 작업을 처리하는 것이 익숙하지 않았는데 Redux-saga와 관련된 자료들을 찾아 공부하다 보니 function*의 키워드로 시작하는 saga 함수들을 작동시키는 원리와 이 함수를 보조하는 watch- 함수들에 사용되는 delay, call, takeEvery 등의 함수들이 정확히 이해되지 않았다.

특히 watch- 함수가 왜 필요한지 여기에 쓰이는 takeEvery와 takeLatest가 어떤 차이가 있는지가 제일 헷갈렸기 때문에 여기에 리덕스 사가의 함수들에 대해 정리하기로 하였다.

takeEvery와 takeLatest를 키워드로 검색했을 때 가장 이해가 잘 되게 정리되어 있어서 아래 블로그에서 참고하면서 정리하였다.

# Redux-saga의 주요 함수

delay

설정된 시간 이후에 resolve하는 Promise 객체를 리턴한다.

ex.

delay(1000); // 1초 기다리기

put

특정 액션을 dispatch하도록 한다.

ex.

put( { type : "INCREMENT" } ); // INCREMENT action을 dispatch 한다.

takeEvery

들어오는 모든 액션에 대해 특정 작업을 처리해 준다.

ex.

takeEvery("INCREMENT_ASYNC", incrementAsync); // 들어오는 모든 INCREMENT_ASYNC 액션에 대해 increaseSaga 함수 실행

+ 모든 액션을 유효하게 인정, while(true)로 감싸는 효과, 로그인 버튼을 눌러 LOG_IN_REQUEST 요청을 받고 LOG_IN_SUCCESS를 실행시키는 비동기 작업에서 takeEvery를 사용하지 않으면 다음 로그인 버튼을 눌렀을 때 요청만 받고 실행되어야 할(put되어야 할) 동작이 이행되지 않는다.

ex.

takeLatest

기존에 진행 중이던 작업이 있다면 취소 처리하고 가장 마지막으로 실행된 작업만 수행한다.

ex.

takeLatest(REGISTER, registerSaga); // REGISTER 액션에 대해서 기존에 진행중이던 작업이 있다면 취소 처리하고 가장 마지막으로 실행된 작업에 대해서만 registerSaga함수를 실행한다. (실수로 로그인이나 회원가입 버튼을 연달아 누르는 경우 서버에 요청이 여러 번 가지 않도록 할 때 사용한다.

call

함수의 첫 번째 파라미터는 함수, 나머지 파라미터는 해당 함수에 넣을 인수이다.

ex.

call(delay, 1000) // delay(1000)

call 과 put 의 차이점은 put은 스토어에 인자로 들어온 action을 dispatch하고, call은 주어진 함수를 실행하게 된다.

fork

함수의 비동기적인 호출을 할 때 사용, call과 달리 순서 상관 없이 실행할 때 사용

ex.

all( [ fork(fetchData) ] ) // all( [ fork(f1), fork(f2) ] ) f1과 f2를 순서 상관 없이 실행시킨다. all과 함께 사용하는 것을 볼 수 있다.

all

all 함수를 사용해서 제네레이터 함수를 배열의 형태로 인자에 넣어주면, 제네레이터 함수들이 병행으로 동시에 실행되고, 전부 resolve될 때까지 기다린다. Promise.all과 비슷하다고 보면 된다.

ex.

all(fork(fetchData), debouce(500, types.TRY_SET_TEXT, trySetText) ] ); // fork(fetchData)와 debounce가 동시에 실행되고 모두 resolve 될 때까지 기다린다.