上下文:使用Angular2在TypeScript中编写的应用程序,+ rxjs 5.
编辑:我正在准备我对Rx库相对较新,以及应该采用“惯用方式”的方式。是的,在发布SO之前,我试图在文档中找到一些线索。
我有这个:
class Result { constructor(public inError: boolean) { } }
const checks : Array<() => Observable<Result>> = [...];
这是一个函数数组,每个函数返回一个包含Result对象的observable。
我想要的是什么:
Array<Observable<Result>>
,
基本上是依次调用每个函数...... Result.inError
成立时立即打破'地图'!我被卡住了,摆弄reduce
,takeWith
,contains
等...
Observables的延迟性质令我感到困惑。
非常感谢任何帮助!
答案 0 :(得分:0)
如果您的observable正在执行同步操作,您只需执行此操作:
const results = [];
for (const i = 0; i < checks.length; i +=1) {
checks[i]().subscribe(result => if (result.inError) {
break;
} else {
results.push(checks[i]());
});
}
// Results observables accessible here.
在异步观察者案例中:
const results = [];
function callObservable(index) {
checks[index]().subscribe(result => if (result.inError) {
// Results observables accessible here.
} else {
results.push(checks[i]());
callObservable(index + 1);
})
}
callObservable(0);
但是,做任何这些都不会带来任何好处。您的observable在它们甚至到达结果数组之前已经被调用,或者如果再次从该数组调用,则会有另一个值。
答案 1 :(得分:0)
经过越来越多的挖掘,这是一个解决方案:
// Some class that will be contained in my observables
class Result { constructor(public inError: boolean) { } }
// An array of Observables that will emit those classes instances
// the thunk is just here to lazy instantiate the Result classes
// only when needed
const oResults : Array<() => Observable<Result>> = [
Rx.Observable.of(() => new Result(false)),
Rx.Observable.of(() => new Result(false)),
Rx.Observable.of(() => new Result(true)),
Rx.Observable.of(() => new Result(false))
];
// An home made (found on SO) INCLUSIVE 'takeWhile' version
const takeWhileInclusive(source, predicate){
return source.publish(co => co.takeWhile(predicate)
.merge(co.skipWhile(predicate).take(1)));
}
// Let's filter out things as expected
const res = takeWhileInclusive(
Rx.Observable.merge(oResults).map( x => x()),
x => !x.inError
);
// I can now subscribe to the resulting stream and will only get
// all the first Results that are false AND the first following result that
// is true
res.subscribe(next => console.info("Next result", next));