Rxjs 在redux observable中,如何在同一史诗中发出动作和流?

Rxjs 在redux observable中,如何在同一史诗中发出动作和流?,rxjs,redux-observable,Rxjs,Redux Observable,我正在尝试将我的executeWithRetries实用程序(见下文)升级到最新版本的redux observable,其中不再允许在epic中进行调度 当前,此实用程序会查看所需令牌是否过期,如果过期,则会发送刷新令牌操作,并返回一个新的操作$,该操作通过执行原始请求(包括新令牌)响应生成的刷新令牌操作。这是正确的 如果不显式地分派操作,我如何能够同时执行以下操作: 触发刷新\u令牌操作,并 创建一个响应另一个(结果)操作的流 从'ramda'导入{isEmpty}; 从“rxjs/obser

我正在尝试将我的
executeWithRetries
实用程序(见下文)升级到最新版本的
redux observable
,其中不再允许在epic中进行调度

当前,此实用程序会查看所需令牌是否过期,如果过期,则会发送
刷新令牌
操作,并返回一个新的
操作$
,该操作通过执行原始请求(包括新令牌)响应生成的
刷新令牌
操作。这是正确的

如果不显式地分派操作,我如何能够同时执行以下操作:

  • 触发
    刷新\u令牌
    操作,并
  • 创建一个响应另一个(结果)操作的流
  • 从'ramda'导入{isEmpty};
    从“rxjs/observable/of”导入{of};
    进口{
    作为战术的行动,
    选择apikey,
    选择GuestreFreshToken,
    选择GuestTokenyms,
    类型作为来宾类型,
    }来自“../reducers/guest”;
    const retryOrFail=({requestFactory,failure,success,store})=>{
    const state=store.getState();
    const apiKey=选择apiKey(状态);
    const tokens={apiKey,accessToken};
    返回requestFactory。重试(令牌)
    .map(res=>{
    返回成功(res);
    })
    .catch(错误=>{
    return retryOrFail({requestFactory,failure,success,store});
    });
    };
    常量刷新令牌数=(存储)=>{
    const state=store.getState();
    const guestRefreshToken=选择guestRefreshToken(状态);
    const guestotokenexpiryms=选择guestotokenexpiryms(状态);
    const{dispatch}=store;
    const guestokenexpired=()=>guestrefreshttoken和guestokenexpireyms和guestokenexpireymsretryOrFail({requestFactory,failure,success,store}));
    如有必要(如有必要(储存)){
    返回-返回动作;
    }
    return requestFactoryToUse.execute()
    .map(res=>success(res))
    .catch((错误)=>{
    返回(失败(err.toString());
    });
    }
    
    这可能是因为此代码的结构不再与
    redux兼容-observable@latest
    ,因为它依赖于调度操作,但我不知道处理此情况的其他方法。

    编辑-此解决方案不是最优的-请参阅我的其他答案


    如果我:

  • 导出实例化的
    存储
    ,然后
  • 直接将存储导入我的epic实用程序,并使用
    store.dispatch
  • configureStore.js

    。。。
    export const store=createStore(
    减根剂,
    composeEnhancers(applyMiddleware(epicMiddleware)),
    );
    常量配置存储=()=>{
    运行(rootEpic);
    退货店;
    };
    导出默认配置存储;
    
    (下面的示例epic最好与
    mapTo
    一起使用,或者(甚至更好)在减速器内使用,但无论如何,这证明了其功能):

    cancelOrder.js

    从“../configureStore”导入{store};
    export const CancelOrder=(action$,store,{dispatch})=>action$
    .烟斗(
    类型(类型。取消订单),
    点击(()=>store.dispatch(cancelSideEffectRequestAction)),
    忽略元素()
    );
    
    编辑--此解决方案不是最优的-请参阅我的其他答案


    如果我:

  • 导出实例化的
    存储
    ,然后
  • 直接将存储导入我的epic实用程序,并使用
    store.dispatch
  • configureStore.js

    。。。
    export const store=createStore(
    减根剂,
    composeEnhancers(applyMiddleware(epicMiddleware)),
    );
    常量配置存储=()=>{
    运行(rootEpic);
    退货店;
    };
    导出默认配置存储;
    
    (下面的示例epic最好与
    mapTo
    一起使用,或者(甚至更好)在减速器内使用,但无论如何,这证明了其功能):

    cancelOrder.js

    从“../configureStore”导入{store};
    export const CancelOrder=(action$,store,{dispatch})=>action$
    .烟斗(
    类型(类型。取消订单),
    点击(()=>store.dispatch(cancelSideEffectRequestAction)),
    忽略元素()
    );
    
    可以向epic中间件的依赖项添加
    store.dispatch

    我们需要扩展redux observable的Epic中间件,以包括存储:

    epicMiddleware.js

    从'redux observable'导入{createEpicMiddleware}
    常量=(存储)=>{
    const originalEpicMiddleware=createEpicMiddleware({
    依赖项:{
    调度:store.dispatch,
    },
    })
    const storeMiddleware=originalEpicMiddleware(存储)
    epicMiddleware.run=originalEpicMiddleware.run
    返回存储中间件
    }
    导出默认中间件
    
    然后,我们将我们的epicMiddleware版本包含在商店实例化中:

    store.js

    从'redux'导入{createStore,applyMiddleware};
    从“/epicMiddleware”导入epicMiddleware;
    从“/rootEpic”导入rootEpic;
    从“/rootReducer”导入rootReducer;
    const store=createStore(
    减根剂,
    [],
    applyMiddleware(epicMiddleware),
    );
    运行(rootEpic);
    导出默认存储;
    
    最后,我们可以将
    dependencies
    中的
    dispatch
    包含在史诗中,如下所示:

    triggerEpic.js

    从'rxjs/operators'导入{ignoreElements,tap};
    从'redux observable'导入{ofType};
    const triggerEpic=(action$,state$,{dispatch})=>
    动作$.pipe(
    类型('TRIGGER\u EPIC
    
    action$.pipe(
      ofType('SOME_TYPE'),
      op.mergeMap(action => {
        const onSuccess$ = action$.pipe(
          ofType('TOKEN_REFRESH_SUCCESS'),
          // ...rest of refreshed token logic
        );
        return Rx.merge(Rx.of(refreshToken()), onSuccess$);
      })
    );