Reputation: 571
Is it possible to call store.dispatch synchronously in redux-saga, that is, return after the saga which takes its action finished running. For example, the following code
const { createStore, applyMiddleware } =require('redux')
const createSagaMiddleware =require('redux-saga').default
const { takeEvery ,take,fork,put}=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() {
const action=yield take('testTake')
yield delay(1000);
console.log('from takeSaga')
}
sagaMiddleware.run(takeSaga)
const main=async ()=>{
store.dispatch({type: 'testTake'})
console.log("from main");
}
main();
outputs
from main
from takeSaga
That is, the store.dispatch({type: 'testTake'})
returns after takeSaga
executed the yield delay(1000)
statement. What I want to archive is that the store.dispatch({type: 'testTake'})
returns only after the takeSaga
has finished its last statement console.log('from takeSaga')
, so that the expected output should be
from takeSaga
from main
Is that possible? I have tried await store.dispatch({type: 'testTake'})
but without success.
Upvotes: 1
Views: 2996
Reputation: 67459
To my knowledge, no, that's not possible.
store.dispatch()
is, by itself, 100% synchronous. When you call it, it runs your reducer, runs any subscription callbacks, and returns.
Middleware can change that, by intercepting actions and delaying them in some way. But, if a middleware intercepts and delays an action, the original dispatch()
call will still return, because this particular event loop needs to run to completion.
In your example, what happens is:
next(action)
, eventually reaching the real store.dispatch
store.dispatch
returnsnext(action)
returns, and the saga middleware continues executingdelay()
effect, telling the middleware it wants to wait before it continues. The yield
statement pauses your saga.So, the delay()
effect causes the middleware to finish up its current work and return. You can't make the event loop block for a second with that.
Upvotes: 1