Functional reactive operator for custom filter based on another Observable

淺唱寂寞╮ 提交于 2019-12-05 19:50:27

In RxJS:

var state = Rx.Observable.interval(2000)
  .map(s => ({type:'s', value: s}))
  .take(3);
var undo = Rx.Observable.interval(3000)
  .map(u => ({type:'u', value: u}; }))
  .take(1);

var save = state.merge(undo).scan((prev, curr) =>
  if (prev.type === 'u') {
    return {type: 'removed'};
  } else {
    return curr;
  }
}).filter(x => x.type !== 'removed' && x.type !== 'u');

See this JSBin. The trick is merge is a vertical combinator (vertical with regards to the streams diagram), and scan is a horizontal combinator. Using both, first merge, then scan, you are able to build more powerful combinators like the one that solves your problem. The solution is similar in Bacon and Kefir.

With Bacon.js, I would use the Bacon.update function to maintain a property with the whole undo stack. This way, we can support multiple successive undo steps.

var state = Bacon.sequentially(1000, [1,2,3])
var undo = Bacon.later(2500, "undo")

var stateStack = Bacon.update(
[],
state, function(prev, s) { return prev.concat(s) },
undo, function(prev, u) { return prev.slice(0, prev.length - 1) }
)

var currentState = stateStack.changes().map(function(stack) {
  return stack[stack.length-1]
})

stateStack.log()
currentState.log()

http://jsbin.com/boharo/2/edit?js,console

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!