呼吁阵列实体法和孩子ReactiveX

问题描述 投票:1回答:1

我想从一个树创建一个可观察的。每个节点将产生可观察到的,其依赖于可观察到它的父(例如经由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),并且永远不会执行完整的回调。这是为什么?

谢谢!

javascript typescript rxjs reactivex
1个回答
1
投票

这里的主要问题是,你是不是添加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); } }) ); }

© www.soinside.com 2019 - 2024. All rights reserved.