这可以用RxJs完成吗?
更新:以下是我的活动流的JsBin演示(请查看评论)http://jsbin.com/jepesu/1/edit?js,console,output
答案 0 :(得分:0)
我找到了解决问题的方法。事件看起来像这样:
{
id: 0, // unique
title: 'xxx',
sound: 'p0', // One of 'p0', 'p1', 'p2'
playSound: false, // If the sound should be played
}
只有在最近5秒钟内没有播放相同类型的声音时,才会播放声音。 playSound
是我要切换的布尔值。为此,我需要一个辅助函数:throttleMap
/**
* Executes a map function on the first element in the window, returns the rest as is
* In other words: Executes mapFunction on all elements the Rx.throttle() function would
* emit, emits all other elements unchanged
*/
Rx.Observable.prototype.throttleMap = function (windowDuration, mapFunction, scheduler) {
Rx.Scheduler.isScheduler(scheduler) || (scheduler = Rx.Scheduler.default);
var duration = +windowDuration || 0;
if (duration <= 0) { throw new RangeError('windowDuration cannot be less or equal zero.'); }
var source = this;
return new Rx.AnonymousObservable(function (o) {
var lastOnNext = 0;
return source.subscribe(
function (x) {
var now = scheduler.now();
if (lastOnNext === 0 || now - lastOnNext >= duration) {
lastOnNext = now;
o.onNext(mapFunction(x));
}
else {
o.onNext(x);
}
},function (e) { o.onError(e); }, function () { o.onCompleted(); }
);
}, source);
};
现在的解决方案:
const groupedSoundStream = singleNotificationStream
.groupBy(
(x) => x.sound,
(x) => x
)
.flatMap((x) => {
return x.throttleMap(5000, (x) => {
x.playSound = true
return x
})
})
groupedSoundStream
.subscribe((x) => console.log(secSinceStart()+'s', x))
一些示例输出:
0.3s { id: 0, title: 'M#0', sound: 'p2', playSound: true }
0.6s { id: 1, title: 'M#1', sound: 'p1', playSound: true }
0.9s { id: 2, title: 'M#2', sound: 'p1', playSound: false }
1.2s { id: 3, title: 'M#3', sound: 'p0', playSound: true }
1.5s { id: 4, title: 'M#4', sound: 'p2', playSound: false }
1.8s { id: 5, title: 'M#5', sound: 'p0', playSound: false }
2.1s { id: 6, title: 'M#6', sound: 'p1', playSound: false }
2.4s { id: 7, title: 'M#7', sound: 'p2', playSound: false }
2.7s { id: 8, title: 'M#8', sound: 'p2', playSound: false }
3.1s { id: 9, title: 'M#9', sound: 'p1', playSound: false }
3.4s { id: 10, title: 'M#10', sound: 'p1', playSound: false }
3.7s { id: 11, title: 'M#11', sound: 'p1', playSound: false }
4s { id: 12, title: 'M#12', sound: 'p2', playSound: false }
4.3s { id: 13, title: 'M#13', sound: 'p0', playSound: false }
4.6s { id: 14, title: 'M#14', sound: 'p2', playSound: false }
4.9s { id: 15, title: 'M#15', sound: 'p1', playSound: false }
5.2s { id: 16, title: 'M#16', sound: 'p2', playSound: false }
5.5s { id: 17, title: 'M#17', sound: 'p2', playSound: true }
5.8s { id: 18, title: 'M#18', sound: 'p0', playSound: false }
6.1s { id: 19, title: 'M#19', sound: 'p2', playSound: false }
6.4s { id: 20, title: 'M#20', sound: 'p1', playSound: true }
6.7s { id: 21, title: 'M#21', sound: 'p2', playSound: false }
7s { id: 22, title: 'M#22', sound: 'p1', playSound: false }