问题描述
我想遍历一系列异步函数,并在返回false时结束迭代。
我是rxjs
的新手,无法使用以下用例。我觉得我不了解一些基本知识。有人可以向我指出吗?
function validateA(): Observable<any> {
// do stuff.
return of({ id: "A",result: true }); // hardcoding result for Now
}
function validateB(): Observable<any> {
// do stuff
return of({ id: "B",result: true }); // hardcoding result for Now
}
function validateC(): Observable<any> {
// do stuff
return of({ id: "C",result: false });// hardcoding result for Now
}
from([validateA,validateB,validateC])
.pipe(
map(data => data()),takeWhile(data => !!data.result)
)
.subscribe(data => console.log(`${data.id} passed!`));
https://stackblitz.com/edit/typescript-ub9c5r?file=index.ts&devtoolsheight=100
解决方法
以下似乎可以解决问题,并懒惰地调用函数:
https://stackblitz.com/edit/typescript-9ystxv?file=index.ts
import { from,Observable,of } from "rxjs";
import { concatAll,find,map } from "rxjs/operators";
function validateA() {
console.log('validateA');
return of({ id: "A",result: false });
}
function validateB() {
console.log('validateB');
return of({ id: "B",result: true });
}
function validateC() {
console.log('validateC');
return of({ id: "C",result: false });
}
from([validateA,validateB,validateC])
.pipe(
map(validate => validate()),concatAll(),find(data => data.result)
)
.subscribe(data => console.log(`${data.id} passed!`));
,
我要说的是,您逻辑的核心是正确的。缺少的是rxJs的特殊之处。
解决方案可能是这样的。注释中有细微差别的解释。
// start from an array of functions and turn it into a stream using RxJs from function
from([validateA,validateC])
.pipe(
// now execute each function sequentially,one after the other,via concatMap
// operator. This operator calls each function and each function returns an Observable
// concatMap ensures that the functions are called sequentially and also that the returned Observable (because each function returns an Observable)
// is "flattened" in the result stream. In other words,you execute each function one at the time
// and return the value emitted by the Observable returned by that function
// until that Observable completes. Considering that you use the "of" function to
// create the Observable which is returned by each function,such Observable emits just one value and then completes.
concatMap(func => func()),// now you have a stream of values notified by the Observables returned by the functions
// and you terminate as soon as a flase is received
takeWhile(data => !!data.result)
)
.subscribe(data => console.log(`${data.id} passed!`));