function* generator(){
  let index = 0;
  while (index <= 2) { // while(true)일 경우 무한 반복
    yield index++;
  }
}
let iterator = generator();
console.log(iterator.next()); // { value: 0, done: false }
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
Generator : 빠져나갔다가 나중에 다시 돌아와도 사용가능한 함수. 이때 컨텍스트(변수 값)는 출입 과정에서 저장된 상태로 남아 있다.
사용 : 제네레이터 함수가 호출되면 바로 실행하지 않고 iterator(반복기) 객체로 반환되고 next() 메소드를 사용하면 함수의 yield 부분의 값을 돌려주고 멈춤. (다음 실행시 중단된 위치에서 시작)
value: yield 된 값
done : 더 진행할 수 있으면 (yield가 더 존재) false, 끝났으면 true
흐름을 끊고 재개하는 방식으로 비동기->동기 작업에 사용가능.
redux-saga
리덕스 미들웨어 라이브러리로, generator 방식을 사용해 비동기 -> 동기 작업을 보다 쉽게 해준다.
사가는 (이펙트에 따라) next를 알아서 해주는 제네레이터이다.
function loadMainPostsAPI() {
  return axios.get('/posts')
}
function* loadMainPosts() {
  try {
    const result = yield call(loadMainPostsAPI)
    yield put({
      type: LOAD_MAIN_POSTS_SUCCESS,
      data: result.data
    })
  } catch (e) {
    yield put({
      type: LOAD_MAIN_POSTS_FAILURE,
      error: e
    })
  }
}
function* watchLoadMainPosts() {
  yield takeLatest(LOAD_MAIN_POSTS_REQUEST, loadMainPosts)
}
export default function* postSaga() {
  yield all([fork(watchLoadMainPosts),])
}
[출처] https://github.com/ZeroCho/react-nodebird
fork : 함수호출(비동기)
call : 함수호출(동기)
put : 액션 dispatch
takeLatest : 액션이 dispatch되는 것을 기다려서 dispatch될때 generator를 호출 (맨 뒤에꺼만)
takeEvery : 액션이 dispatch되는 것을 기다려서 dispatch될때 generator를 호출 (전부)