call을 이용해서 비동기함수를 호출한다면 동기적으로 함수가 종료되고 반환할 때까지 기다려야한다. 하지만 호출 중간에 우발적으로 일어나는 다른 액션 또한 동작하기를 원한다면 fork을 이용해야한다.
import { take, call, put, cancelled } from 'redux-saga/effects'
import Api from '...'
function* loginFlow() {
while (true) {
const {user, password} = yield take('LOGIN_REQUEST')
// LOGIN_REQUEST 액션을 pull한다.
const task = yield fork(authorize, user, password)
// authorize 함수 호출 명령을 실행한다.
const action = yield take(['LOGOUT', 'LOGIN_ERROR'])
// authorize 함수 호출 명령의 결과를 기다리는 동안 LOGOUT,LOGIN_ERROR가 있을 경우 결과를 기다리지 않고 액션을 pull한다.
if (action.type === 'LOGOUT')
yield cancel(task)
yield call(Api.clearItem, 'token')
}
}
import { delay } from 'redux-saga'
import { fork, call, put } from 'redux-saga/effects'
import api from './somewhere/api' // app specific
import { receiveData } from './somewhere/actions' // app specific
function* fetchAll() {
const task1 = yield fork(fetchResource, 'users')
const task2 = yield fork(fetchResource, 'comments')
yield call(delay, 1000)
}
function* fetchResource(resource) {
const {data} = yield call(api.fetch, resource)
yield put(receiveData(data))
}
function* main() {
yield call(fetchAll)
}
function* fetchAll() {
const task1 = yield fork(fetchResource, 'users')
const task2 = yield fork(fetchResource, 'comments')
yield call(delay, 1000)
}
function* fetchResource(resource) {
const {data} = yield call(api.fetch, resource)
yield put(receiveData(data))
}
function* main() {
try {
yield call(fetchAll)
// 자식 중 하나가 실패한다면 대기 중인 effect를 취소하고 main 안의 catch에 잡힐 것이다.
} catch (e) {
// handle fetchAll errors
}
}