根据有效负载延迟史诗动作

时间:2018-01-29 09:58:08

标签: angular angular-redux

根据documentation,在一个可观察的内容中延迟一个动作非常简单:

const pingEpic = action$ =>
  action$.ofType('PING')
    .delay(1000) // Asynchronously wait 1000ms then continue
    .mapTo({ type: 'PONG' });

但是我想根据动作有效负载中的某些值来延迟动作。例如这样的事情(什么不起作用):

const pingEpic = action$ =>
  action$.ofType('PING')
    .delay(action => action.payload.delayTime) // Asynchronously wait the time defined within the action then continue
    .mapTo({ type: 'PONG' });

不幸的是.delay()只需要一个简单的静态值,我不知道如何设置动作的值。有人有想法吗?

为什么需要它?

这种行为背后的原因是,我在我的史诗中调用了一个REST API,它在后端创建了一个新项目。当这个调用返回时,我将触发两个动作(通过flatMap)。一个成功的操作是让reducer更新相应的状态,另一个动作来获取后端中所有可用项的列表。不幸的是后端有点慢(而且我无法控制它),因此对所有项目的立即调用会返回一个没有新创建项目的列表。 500分钟后执行相同的呼叫会按预期返回任何内容。导致这个"得到整个列表请求"与第一次显示页面时完全相同,我不希望所有请求都有这种延迟,但只有在创建调用后才会触发。所以我的想法是为动作添加一个延迟参数(默认值为零),然后将从史诗中考虑。

如果没有人能告诉我如何从动作中得到延迟,第二种可能性就是使用另一种动作,其他史诗只是听取并使用某种硬编码延迟,但如果我能用它会很酷通过相同的动作对此进行参数化。

1 个答案:

答案 0 :(得分:1)

你可以使用delayWhen执行此操作,但它有点笨重(它与takeUntil类似):

const pingEpic = action$ => action$.ofType('PING')
  .delayWhen(({ payload: { delayTime }}) => Observable.timer(delayTime)) 
  .mapTo({ type: 'PONG' });

因此,delayWhen延迟原始Observable,直到回调函数返回Observable发出一些内容。然后它会恢复原始Observable,因此如果您之后有map而不是mapTo,则可以映射原始操作/有效负载/无论如何。