我想从一个树创建一个可观察的。每个节点将产生可观察到的,其依赖于可观察到它的父(例如经由switchMap
)。在树的每一层,需要合并每个孩子的观测。
我希望如此,它使用可观察到这种代码转换:
interface Request {
name: string;
childrens?: Request[];
}
start() {
this.nextRequests(this.requests);
}
private nextRequests(requests: Requests[]) {
requests.forEach(request => {
this.socketService.message(request.name, (res) => {
if (request.childrens) {
this.nextRequests(request.childrens, res);
}
});
});
}
所以,这就是我认为这将是这样的:
interface Request {
name: string;
childrens?: Request[];
}
// This isn't right.
// SocketService.message return a observable, the reponse of the request.
start(requests: Request[]): Observable<any> {
return from(requests).pipe(switchMap(request => {
return this.socketService.message(request.name);
}), concatMap(request => {
if (request.childrens) {
return this.start(request.childrens);
}
return of(request.name);
}));
}
const mock: Request[] = [
{name: 'test1', childrens: [
{ name: 'test4' },
{ name: 'test5' }
]},
{ name: 'test2' },
{ name: 'test3' }
];
this.start(mock).subscribe((name) => {
console.log(`Request ${name} done`);
}, err => { }, () => {
console.log('Complete');
});
并且输出应该是这样的:
Request test1 done
Request test2 done
Request test3 done
Request test4 done
Request test5 done
Complete
而是我得到这个:
Request test2 done
Request test3 done
Request test4 done
Request test5 done
兄弟节点之间发射的顺序并不重要。但家长带孩子不打印(test1
),并且永远不会执行完整的回调。这是为什么?
谢谢!
这里的主要问题是,你是不是添加test1
元素作为参数去
if (request.childrens) {
return this.start(request.childrens);
}
它应该看起来像
if (request.childrens) {
return this.start([{name:request.name},...request.childrens]);
}
通过这样做,您将收到的订阅作为第一价值qazxsw POI,否则它永远不会被记录下来,因为这将是由流类型的过滤。
现在也有在下面的链接BFS-ISH演示
该代码看起来是这样的
test1
这里有一个现场演示function startBFS(requests) {
return merge(from(requests)).pipe(
mergeMap((x, i) => {
if (x.children) {
return concat(of(x), startBFS(x.children));
} else {
return of(x);
}
})
);
}