javascript - 如何仅在流发生变化时对其进行过滤?

标签 javascript reactive-programming reactive-streams

响应式编程新手。我有一个流,一个滚动流,绑定(bind)到 domNode,然后还有一些其他流通过过滤器订阅:

var element = document.getElementById('scrollableElement');
var sourceStream = Rx.Observable.fromEvent(element, 'scroll').map(function(e){
  return e.srcElement.scrollTop;
});

var inTheOneHundreds = sourceStream
  .filter(function (x, idx, obs) {
    return x >= 100 && x < 200;
  });

var inTheTwoHundreds = sourceStream
  .filter(function (x, idx, obs) {
    return x >= 200 && x < 300;
  });

inTheOneHundreds.subscribe(function(value){
  console.log('one hundreds ' + value);
});

inTheTwoHundreds.subscribe(function(value){
  console.log('two hundreds ' + value);
});

输出如下:

one hundreds 193
one hundreds 196
one hundreds 199
two hundreds 201
two hundreds 204

您可以在这里看到:http://jsbin.com/zedazapato/edit?js,console,output

我希望这些新流在数百个更改(从 truefalse)时输出,而不是重复输出:

one hundreds 199
two hundreds 201
one hundreds 170
two hundreds 270
one hundreds 103
two hundreds 200
one hundreds 156

我尝试使用Observable.distinctUntilChanged,但它的行为似乎并不像我预期的那样(它似乎输出相同的东西):http://jsbin.com/gibefagiri/1/edit?js,console,output

我哪里出错了?

最佳答案

您有多种选择。

这将从谓词生成流,当谓词变为 true 时发出一个项目:

var element = document.getElementById('scrollableElement');
var sourceStream = Rx.Observable.fromEvent(element, 'scroll').map(function(e){
  return e.srcElement.scrollTop;
});

function whenBecomesTrue(stream, selector) {
  return stream.distinctUntilChanged(selector).filter(selector);
}

var inTheOneHundreds = whenBecomesTrue(sourceStream, function (x, idx, obs) {
  return x >= 100 && x < 200;
});

var inTheTwoHundreds = whenBecomesTrue(sourceStream, function (x, idx, obs) {
  return x >= 200 && x < 300;
});

inTheOneHundreds.subscribe(function(value){
  console.log('one hundreds ' + value);
});

inTheTwoHundreds.subscribe(function(value){
  console.log('two hundreds ' + value);
});

或者您可以先发出页面更改:

var element = document.getElementById('scrollableElement');
var sourceStream = Rx.Observable.fromEvent(element, 'scroll').map(function(e){
  return e.srcElement.scrollTop;
});

function pageOf(x) {
  return Math.floor(x / 100);
}

var pageChanges = sourceStream.distinctUntilChanged(pageOf);

var inTheOneHundreds = pageChanges.filter(function (x, idx, obs) {
  return pageOf(x) === 1;
});

var inTheTwoHundreds = pageChanges.filter(function (x, idx, obs) {
  return pageOf(x) === 2;
});

inTheOneHundreds.subscribe(function(value){
  console.log('one hundreds ' + value);
});

inTheTwoHundreds.subscribe(function(value){
  console.log('two hundreds ' + value);
});

使用distinctUntilChanged的方法的问题在于它实际上是通过原始scrollTop值(它总是与之前的值不同)来区分的,而不是通过指示数字是否在给定范围内的 bool 值来区分的。

关于javascript - 如何仅在流发生变化时对其进行过滤?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33805692/

相关文章:

javascript - 如何在 jQuery .each() 函数中访问变量?

javascript - 在另一个滚动函数中隐藏/显示滚动上的 div

javascript - 链接到在 react 中不起作用

java - 将 then 与 Mono<Void> 一起使用时出现意外行为

kotlin - 结合多个流动性

javascript - 函数在一个参数上有闭包,而另一个参数是从 promise 返回的?

javascript - 正则表达式限制小数点前后 'n'位数

java - rx-java 中的套接字看门狗

java - doOnNext() 不会被调用 Spring Webflux

java - 只允许一个连接接收订阅者