javascript RxJs:如何根据可观察的状态进行循环?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34246398/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
RxJs: How to loop based on state of the observable?
提问by JBCP
I'm trying to get RxJs to loop over an Observable in my stream until it is in a certain state, then have the stream continue. Specifically I'm converting a synchronous do/while loop to RxJs, but I assume the same answer could be used for a for or while loop as well.
我试图让 RxJs 在我的流中循环一个 Observable 直到它处于某种状态,然后让流继续。具体来说,我正在将同步 do/while 循环转换为 RxJs,但我认为相同的答案也可用于 for 或 while 循环。
I thought I could use doWhile() for this, but it seems like the condition function does not have access to the item in the stream, which seems to defeat the purpose to me.
我以为我可以为此使用 doWhile(),但似乎条件函数无法访问流中的项目,这对我来说似乎违背了目的。
I'm not completely sure what the correct reactive terminology is for what I want, but here is an example of what I am going for:
我不完全确定我想要的正确的反应术语是什么,但这里有一个我想要的例子:
var source = new Rx.Observable.of({val: 0, counter: 3});
source.map(o => {
o.counter--;
console.log('Counter: ' + o.counter);
if (!o.counter) {
o.val = "YESS!";
}
return o;
})
.doWhile(o => {
return o.counter > 0;
})
.subscribe(
function (x) {
console.log('Next: ' + x.val);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
The expected output would be:
预期的输出将是:
Counter: 3
Counter: 2
Counter: 1
Counter: 0
Next: YESS!
Completed
Assuming this is a solvable problem, I am unclear on how you mark the 'start' of where you want to return when you loop.
假设这是一个可解决的问题,我不清楚您如何标记循环时要返回的“开始”。
回答by Niklas Fasching
There is the expandoperator which gets you close by allowing you to recursively call a selector function. Returning an empty observable would be your break in that case. See jsbin:
有一个expand运算符,它允许您递归调用选择器函数,从而使您关闭。在这种情况下,返回一个空的 observable 将是你的休息时间。见jsbin:
var source = Rx.Observable.return({val: 0, counter: 3})
.expand(value => {
if(!value.counter) return Rx.Observable.empty();
value.counter -= 1;
if(!value.counter) value.val = 'YESS';
return Rx.Observable.return(value)
})
.subscribe(value => console.log(value.counter ?
'Counter: ' + value.counter :
'Next: ' + value.val));
回答by user3743222
Not exactly what you want but close, using expand
operator, and signalling end of recursion with Rx.Observable.empty
(http://jsfiddle.net/naaycu71/3/):
不完全是你想要的,而是关闭,使用expand
运算符,并用Rx.Observable.empty
(http://jsfiddle.net/naaycu71/3/)发出递归结束信号:
var source = new Rx.Observable.of({val: 0, counter: 3});
source.expand(function(o) {
console.log('Counter: ' + o.counter);
o.counter--;
return (o.counter >= 0) ? Rx.Observable.just(o) : Rx.Observable.empty()
})
.subscribe(
function (x) {
console.log('Next: ' , x);
},
function (err) {
console.log('Error: ' + err);
},
function () {
console.log('Completed');
});
Output :
输出 :
Next: Object {val: 0, counter: 3}
Counter: 3
Next: Object {val: 0, counter: 2}
Counter: 2
Next: Object {val: 0, counter: 1}
Counter: 1
Next: Object {val: 0, counter: 0}
Counter: 0
Completed