리액트를 다루는 기술을 중 리덕스 사가 구현하는 부분 중 아래와 같이 call 을 설명하는 부분이 있다.
// call을 사용하면 Promise 를 반환하는 함수를 호출하고, 기다릴 수 있습니다.
const post = yield call(api.getPost, action.payload)
근데 call 은 원래 context 바인딩 해주는 것 뿐이고. async/await 처럼 호출하고 기다리게 해준다니?
이터레이터.next() 전까지는 아예 결과 = yield 표현식
자체가 실행이 안 되고, next() 한 후에는 어차피 다음 yield 라인이 실행 안될 텐데 무슨 call 로 비동 기 요청 후 대기를 때리나????
redux-saga/effects 의 call 은
즉, 맞다.
리덕스 액션객체를 왜 만드냐는 생각 해봤다. 결국 리듀서에게 실행을 위힘하기 위해서, 설명서 같은 걸 준다고 생각하면 될 거 같다.
내가 너를 뒤져서 일일히 호출하는 것이 아닌, 나는 너만 호출하고 대신 할 일을 넘기는 것.
유명한... 호주머니 뒤져서 돈 꺼내가는 캐셔일화가 기억나네. 돈 꺼내달라 요청해서 그 행위를 구매자에게 위임하면 되는 거.
검색해서 서술적 이펙트문서를 찾음.
리덕스사가의 effects 중 call 은 자바스크립트 call 과 하는 짓은 같은데, effects 객체를 리턴한다.
구지 안써도 되는 거였음. 다만 테스트 할 때 필요하다고 문서에 적혀있다.
function* 비동기제너레이터() {
const 프로미스결과 = yield Api.fetch('주소')
}
이후 value 로 값을 보면 되는데, assert 테스트를 한다고 하면 구체적인 결과를 넣어야 하고, api 변경이 일어나서 필드가 빠졌다 넣어졌다 하면 그 때마다 그 실제 응답 객체 넣어서 붙여 줘야함.
const 이터레이터 = 비동기제너레이터()
assert.deepEqual(이터레이터.next().value, ??) //
프론트에서 비동기 요청까지만 책임을 지니까. 요청 주소가 올바른지 등만 점검하면 되고 그 응답 결과에 대해서는 테스트 할 필요가 없다.
그래서 리덕스사가 effecs call 을 쓰면
import { call } from 'redux-saga/effects'
function* 비동기제너레이터() {
const products = yield call(Api.fetch, '/products')
// ...
}
yield 결과로 아래 모양의 객체만 생성된다.
{
CALL: {
fn: Api.fetch,
args: ['./products']
}
}
이게 무슨 짓이냐? 이 객체는 단지 설명할 뿐이고. 추후에 이터레이터.next()
호출로 실행이 될 때, 리덕스 사가가 저 객체를 가지고 실행한다.
액션 객체 만들어서 리듀서한테 리턴하면 리듀서에서 실제 실행을 담당하는 것처럼. 예도 그리한다고 설명이 되어있다.(코드는 안 까봤음)
그리고 리덕스 사가가 call 로 생성된 객체를 가지고 비동기 요청을 실행하면, resolve 될 때까지 기다렸다가 resolve 되면 재가동 시킴.
순수 (비동기 요청)행위 설명 객체 덕분에 이제 테스트가 좀 쉬워졌다.
// call 로 생성된 행위객체를 비교검증한다.
assert.deepEqual(
이터레이터.next().value,
call(Api.fetch, '/products'),
"fetchProducts should yield an Effect call(Api.fetch, './products')"
)