Joh*_*han 2 javascript frp reactive-programming rxjs
我正在尝试使用RxJS(使用JQuery扩展),我正在尝试解决以下用例:
鉴于我有两个按钮(A和B),如果在给定的时间范围内点击某个"秘密组合",我想打印一条消息.例如,"秘密组合"可以是在5秒内点击"ABBABA".如果未在5秒内输入组合,则应显示超时消息.这就是我目前拥有的:
var secretCombination = "ABBABA";
var buttonA = $("#button-a").clickAsObservable().map(function () { return "A"; });
var buttonB = $("#button-b").clickAsObservable().map(function () { return "B"; });
var bothButtons = Rx.Observable.merge(buttonA, buttonB);
var outputDiv = $("#output");
bothButtons.do(function (buttonName) {
outputDiv.append(buttonName);
}).bufferWithTimeOrCount(5000, 6).map(function (combination) {
return combination.reduce(function (combination, buttonName) {
return combination + buttonName;
}, "");
}).map(function (combination) {
return combination === secretCombination;
}).subscribe(function (successfulCombination) {
if (successfulCombination) {
outputDiv.html("Combination unlocked!");
} else {
outputDiv.html("You're not fast enough, try again!");
}
});
Run Code Online (Sandbox Code Playgroud)
虽然这很好用,但这并不是我想要的.我需要bufferWithTimeOrCount在新的时间范围内第一次按下按钮A时重置.我正在寻找的是,只要按下秘密组合(ABBABA),我就会想要"组合解锁!" 显示(我不想等待时间窗口过期).
节气门是延迟的典型操作员,具有您想要的反应复位效果.
以下是如何结合扫描使用油门来收集在5秒静音之前输入的组合:
var evaluationStream = bothButtons
.merge(bothButtons.throttle(5000).map(function(){return "reset";})) // (2) and (3)
.scan(function(acc, x) { // (1)
if (x === "reset") return "";
var newAcc = acc + x;
if (newAcc.length > secretCombination.length) {
return newAcc.substr(newAcc.length - secretCombination.length);
}
else {
return newAcc;
}
})
.map(function(combination) {
return combination === secretCombination;
});
var wrongStream = evaluationStream
.throttle(5000)
.filter(function(result) { return result === false; });
var correctStream = evaluationStream
.filter(function(result) { return result === true; });
wrongStream.subscribe(function() {
outputDiv.html("Too slow or wrong!");
});
correctStream.subscribe(function() {
outputDiv.html("Combination unlocked!");
});
Run Code Online (Sandbox Code Playgroud)
(1)我们scan连接输入字符.(2)油门等待事件静音5秒钟,并在沉默之前发出最后一个事件.换句话说,它类似于延迟,除了它在源Observable上看到新事件时重置内部计时器.我们需要重置扫描的连接(1),因此我们只需将相同的限制Observable映射到"reset"标志(3),扫描将其解释为清除累加器(acc).
这是一个JSFiddle.
| 归档时间: |
|
| 查看次数: |
1460 次 |
| 最近记录: |