是否可以在redux-saga中同步调用store.dispatch?

时间:2018-06-22 08:11:21

标签: redux redux-saga

是否有可能在redux-saga中同步调用store.dispatch,即在执行其操作的saga完成后返回。例如,以下代码

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();

输出

from main
from takeSaga

也就是说,store.dispatch({type: 'testTake'})takeSaga执行了yield delay(1000)语句之后返回。我要存档的是store.dispatch({type: 'testTake'})仅在takeSaga完成其最后一条语句console.log('from takeSaga')之后才返回,因此预期输出应为

from takeSaga
from main

有可能吗?我尝试过await store.dispatch({type: 'testTake'}),但没有成功。

1 个答案:

答案 0 :(得分:0)

据我所知,不,那不可能。

df %>% mutate(median = apply(select(., starts_with("X")), 1, median)) 本身是100%同步的。调用它时,它将运行您的reducer,运行所有订阅回调并返回。

中间件可以通过拦截动作并以某种方式延迟它们来改变这种状况。但是,如果中间件拦截并延迟了某个动作,则原始的store.dispatch()调用仍将返回,因为此特定事件循环需要运行才能完成。

在您的示例中,发生的事情是:

  • 传奇的中间件看到了动作,并调用dispatch(),最终到达了真实的next(action)
  • 商店调用根减速器
  • 商店调用所有订户功能
  • store.dispatch返回
  • 返回对store.dispatch的调用,并且传奇中间件继续执行
  • 传奇中间件开始运行需要了解此操作的所有sagas
  • 您的传奇开始运行,并产生next(action)效果,告诉中间件要等待其继续。 delay()语句使您的传奇故事停顿。
  • 中间件认为没有其他sagas关心此操作,因此返回
  • 一秒钟后,超时到期,中间件尝试恢复运行传奇

因此,yield效果使中间件完成其当前工作并返回。如此一来,您就无法使事件循环阻塞。