私はサガが3つの方法で行動を聞いているのを見てきました:
1。while(true)take()
function* onUserDetailsRequest() {
while(true) {
const { userId } = yield take(USER_DETAILS_REQUESTED);
const response = yield call(fetchUserDetails, userId);
put(USER_DETAILS_RECEIVED, response);
}
}
2。while(take())
function* onUserDetailsRequest() {
while(yield take(USER_DETAILS_REQUESTED)) {
const userId = yield select(userSelectorFn);
const response = yield call(fetchUserDetails, userId);
put(USER_DETAILS_RECEIVED, response);
}
}
。takeEvery()
function* onUserDetailsRequest() {
yield takeEvery(USER_DETAILS_REQUESTED, function* (action) {
const { userId } = action;
const response = yield call(fetchUserDetails, userId);
put(USER_DETAILS_RECEIVED, response);
}
}
それぞれの長所と短所は何ですか?そして、どのシナリオで次々に使用する必要がありますか?
@AlexMの答えをコードで明確にするため。
_cat test.js
_
_const { createStore, applyMiddleware } =require('redux')
const createSagaMiddleware =require('redux-saga').default
const { takeEvery ,take,fork}=require('redux-saga/effects')
const {delay} =require('redux-saga')
const sagaMiddleware = createSagaMiddleware()
const reducer=(state=[],action)=>{return [...state,action.type];}
const store = createStore(
reducer,
applyMiddleware(sagaMiddleware)
)
function* takeSaga() {
while(true){
const action=yield take('testTake')
console.log(action)
yield delay(1000)
}
}
function* takeEverySaga() {
yield takeEvery('testTakeEvery',function* (action){
console.log(action)
yield delay(1000)
})
}
function* takeSagaWithFork() {
while(true){
const action=yield take('testTakeWithFork')
yield fork(function*(){
console.log(action)
yield delay(1000)
})
}
}
sagaMiddleware.run(takeSaga)
sagaMiddleware.run(takeEverySaga)
sagaMiddleware.run(takeSagaWithFork)
const main=async ()=>{
store.dispatch({type: 'testTake'})
store.dispatch({type: 'testTake'})
store.dispatch({type: 'testTakeEvery'})
store.dispatch({type: 'testTakeEvery'})
store.dispatch({type: 'testTakeWithFork'})
store.dispatch({type: 'testTakeWithFork'})
}
main();
_
上記のコードを_node test.js
_で実行すると出力されます
_{ type: 'testTake' }
{ type: 'testTakeEvery' }
{ type: 'testTakeEvery' }
{ type: 'testTakeWithFork' }
{ type: 'testTakeWithFork' }
_
違いがわかりますか? takeSaga
のタスクは、2番目のtestTake
アクションがディスパッチされたときにスリープしているため、takeSaga
は2番目のtestTake
アクションを単に無視しました。ただし、takeEverySaga
とtakeSagaWithFork
の場合、testTakeEvery
アクションを受信するたびに新しいタスクがフォークされたため、彼らは独自のタスク「スレッド」でスリープしていたため、新しいアクションが勝ちました見逃すことはありません。したがって、takeEvery
は基本的にwhile(true)
+ take
+ fork
と同じです。