javascript - ReactiveX 中数组实体和子项的调用方法

标签 javascript typescript rxjs reactivex

我想从树中创建一个可观察对象。每个节点都会生成一个依赖于其父节点的可观察对象(例如通过 switchMap)。在树的每一层,每个 child 的可观察值都需要合并。

我想转换这段代码,以便它使用可观察对象:

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

兄弟节点之间的发射顺序并不重要。但是没有打印有 child 的 parent (test1),并且永远不会执行完整的回调。这是为什么?

谢谢!

最佳答案

这里的主要问题是您没有将 test1 元素作为参数添加到

if (request.childrens) {
  return this.start(request.childrens);
}

应该是这样的

if (request.childrens) {
  return this.start([{name:request.name},...request.childrens]);
}

通过这样做,您将收到订阅中的 test1 作为第一个值,否则它永远不会被记录,因为它会被流过滤掉。

编辑:

现在下面的链接中还有 BFS-ish 演示

代码是这样的

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);
      }
    })
  );
}

这是一个现场演示 codeSandbox

关于javascript - ReactiveX 中数组实体和子项的调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54525518/

相关文章:

javascript - 是否可以使用 js 生成 csrf token 并使用 php 验证它?

javascript - 如何执行: onClick Javascript,隐藏具有过渡效果的div

typescript - 基于条件类型的狭义类型(Typescript)

angular - 网络包错误 : Final loader didn't return a Buffer or String

javascript - 如何实现关系/嵌套可观察量?

reactjs - 围绕 Angular2 的架构模式 : Redux, Flux、React、Reactive、RxJS、Ngrx、MVI、

javascript - 如何将纹理应用于自定义几何体

javascript - 以编程方式设置 Javascript 实例变量

c# - 检查 List<T> 的项目是否有效

javascript - 如何创建一个 Observable<any[]>?