满足条件时暂停史诗,然后在条件完成后发出缓冲操作

时间:2017-11-03 16:47:22

标签: redux rxjs redux-observable

我正在开发一个应用程序,当用户在页面之间导航时,我会定期将信息保存到服务器。

我们目前通过安排" persist"动作,在完成" persist_end"之前传播一系列有序的事件。行动。目前,如果用户快速导航,则这些分组的动作可以相互拦截,从而导致各种问题。我以为我可以缓冲启动操作并等到结束操作执行完毕。

我使用Redux-Observables网站上的乒乓示例创建了一个类似的示例:https://codepen.io/dualcyclone/pen/GOZRxW?editors=0011

const actionPauser = new BehaviorSubject(false);

const pingEpic = action$ =>
    action$.ofType(PING)
      .do(action => console.log(action)) // check if action caught by epic
      .buffer(actionPauser.asObservable().filter(paused => !paused))
      .do(eh => console.log('buffered? ',eh)) // check if buffered actions is occurring
      .do(() => actionPauser.next(true)) // tell pauser to pause
      .map((buf) => buf[buf.length-1])
      .filter(action => action !== undefined)
      .delay(1000)
      .mapTo({ type: PONG });

const pauseEpic = action$ =>
    action$.ofType(PONG)
      .delay(1000)
      .do(() => actionPauser.next(false)) // tell pauser to not pause
      .mapTo({ type: PING });

前提是类似的,我允许用户按下"开始PING"按钮按照他们的喜好,正在收听的史诗应检查当前是否存在ping操作(通过" actionPauser" BehaviorSubject),并排队任何操作,直到之前的ping动作为止完成。

史诗应该发出最新的缓冲动作,因此它会过滤缓冲列表,然后通过最新的缓冲列表。

我似乎无法理解的是 - 控制台日志指示一旦页面加载就会触发多少缓冲操作;这可能表明这种方式存在问题 - 我错过了什么吗?

2 个答案:

答案 0 :(得分:2)

所以,虽然动作的输出并不完全合乎需要(因为用户事件发出了起动动作,我不能做太多关于它的事情),Cartant推荐的建议实际上正是我所需要的。

Audit

  

忽略由另一个Observable确定的持续时间的源值,然后从源Observable发出最新值,然后重复此过程。

从本质上讲,这可以让我忽略多次发射的“PING”。当前正在进行的活动。然后它将继续执行最后一次最新的PING'事件,所以我们看到的输出如下:

(click) PING (click) PING (click) PING (click) PING PONG DONE PONG DONE

第一个和最后一个' PING'动作是唯一通过Epic传播的动作,所以我们看到两个最终的PONG动作,然后是DONE动作。

所以,这是一个经过回答的例子(也见于我的codepen here

const pingEpic = action$ =>
  action$.ofType(PING)
    .audit(() => actionPauser.filter(paused => !paused))
    .do(() => actionPauser.next(true))
    .delay(1000)
    .mapTo({ type: PONG });

const pauseEpic = action$ =>
  action$.ofType(PONG)
    .delay(1000)
    .mapTo({ type: DONE })
    .do(() => actionPauser.next(false));

答案 1 :(得分:0)

在这种情况下,concatMap之类的声音可能效果很好。

  

将每个源值投影到一个Observable,它在输出Observable中合并,以序列化的方式等待每一个在合并下一个之前完成。

因此,在下面的情况中,一次只运行一个计时器。

将缓冲前一个仍在等待的任何PING
VPC1

https://jsbin.com/gocezut/edit?js,output

NAT SG

请记住,大多数redux-observable问题可以重新定义为常规RxJS问题,扩展资源并帮助您找到。这就是redux-observable的美妙之处:它几乎完全只是常规的RxJS模式。