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

问题描述 投票:0回答:1

是否可以在redux-saga中同步调用store.dispatch,即在执行其action的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'})
但没有成功。

redux redux-saga
1个回答
1
投票

据我所知,不,这是不可能的。

store.dispatch()
本身是 100% 同步的。 当您调用它时,它会运行您的减速器,运行任何订阅回调,然后返回。

中间件可以通过拦截操作并以某种方式延迟它们来改变这一点。 但是,如果中间件拦截并延迟某个操作,原始

dispatch()
调用仍将返回,因为这个特定的事件循环需要运行完成。

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

  • saga中间件看到动作,并调用
    next(action)
    ,最终达到真正的
    store.dispatch
  • 商店调用根减速器
  • 商店调用所有订阅者功能
  • store.dispatch
    回归
  • next(action)
    的调用返回,saga中间件继续执行
  • saga 中间件开始运行任何需要了解此操作的 sagas
  • 您的传奇开始运行,并产生
    delay()
    效果,告诉中间件它需要等待才能继续。
    yield
    语句暂停你的传奇。
  • 中间件发现没有其他传奇关心此操作,并返回
  • 一秒钟后,超时到期,中间件尝试恢复运行您的传奇

因此,

delay()
效果导致中间件完成当前工作并返回。 你不能用它来阻止事件循环一秒钟。

© www.soinside.com 2019 - 2024. All rights reserved.