如何在Redux-Observable的Epic中根据Action Payload设置延迟?
动态设置Redux-Observable Epic中的Action延迟
这个场景我太熟悉了!delay操作符确实只能接受静态的延迟时长,没法直接从action里取动态值,但RxJS提供了delayWhen操作符,正好能解决这个问题。
核心解决方案:使用delayWhen替换delay
delayWhen允许我们传入一个函数,这个函数会接收当前的action作为参数,返回一个Observable——当这个返回的Observable发出值时,原action才会继续向下流转。我们可以用timer来创建对应时长的延迟Observable,代码示例如下:
const pingEpic = action$ => action$.ofType('PING') .delayWhen(action => timer(action.payload.delayTime)) // 从action的payload里获取延迟时长 .mapTo({ type: 'PONG' });
适配你的业务场景
结合你提到的创建条目后延迟请求列表的需求,我们可以这样实现:
首先,在创建成功后触发的FETCH_ITEM_LIST action里带上延迟参数(默认设为0,不影响正常的列表请求):
const createItemEpic = action$ => action$.ofType('CREATE_ITEM') .flatMap(action => ajax.post('/api/items', action.payload) .flatMap(response => Observable.of( { type: 'CREATE_ITEM_SUCCESS', payload: response }, // 给这个列表请求action加上延迟参数 { type: 'FETCH_ITEM_LIST', payload: { delay: 500 } } ) ) );
然后在处理FETCH_ITEM_LIST的Epic中,用delayWhen动态读取延迟值:
const fetchItemListEpic = action$ => action$.ofType('FETCH_ITEM_LIST') // 读取payload中的delay,默认0,不影响普通请求 .delayWhen(action => timer(action.payload.delay || 0)) .flatMap(() => ajax.get('/api/items') .map(response => ({ type: 'FETCH_ITEM_LIST_SUCCESS', payload: response })) .catch(error => Observable.of({ type: 'FETCH_ITEM_LIST_FAILED', error })) );
这样一来,只有从创建操作触发的FETCH_ITEM_LIST会延迟500毫秒执行,页面首次加载的正常请求不受影响,完全不需要新增额外的Action类型,完美契合你的需求。
内容的提问来源于stack exchange,提问作者Oliver
相关产品推荐
相关产品推荐

