如何仅在流发生变化时过滤流?
How can I filter a stream only when it changes?
响应式编程的新手。我有一个流,一个滚动流,绑定到一个 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
我希望这些新流在百位变化时输出(从true
到false
),而不是重复输出:
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
我哪里错了?
您有多种选择。
这将从谓词生成流,当谓词变为真时发出一个项目:
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 值(它总是与先前的值不同)来区分的,而不是通过指示数字是否在给定范围内的布尔值来区分的。
响应式编程的新手。我有一个流,一个滚动流,绑定到一个 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
我希望这些新流在百位变化时输出(从true
到false
),而不是重复输出:
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
我哪里错了?
您有多种选择。
这将从谓词生成流,当谓词变为真时发出一个项目:
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 值(它总是与先前的值不同)来区分的,而不是通过指示数字是否在给定范围内的布尔值来区分的。