Angular 使一个在另一个完成后可见

Angular 使一个在另一个完成后可见,angular,rxjs,Angular,Rxjs,我同意以下观点: this.router.events .filter(event => event instanceof NavigationEnd) .startWith({}) .pairwise() .subscribe((events: [NavigationEnd, NavigationEnd]) => { if ( this.breadcrum

我同意以下观点:

    this.router.events
        .filter(event => event instanceof NavigationEnd)
        .startWith({})
        .pairwise()
        .subscribe((events: [NavigationEnd, NavigationEnd]) => {
            if (
                this.breadcrumbs.length > 0 &&
                events[0].url &&
                events[0].url.split("?")[0] === events[1].url.split("?")[0]
            ) {
                return;
            }
            let root: ActivatedRoute = this.activatedRoute.root;
            this.breadcrumbs = this.getBreadcrumbs(root);

            this.checkSetIsHomePage();
            this.setBreadcrumbHeight();
        });
我想订阅下面的observable,当上面的一个完成时:

    this.breadcrumbService.additionalBreadcrumbs
        .takeUntil(this.destroy$)
        .subscribe(breadcrumb => {
            if (breadcrumb.index) {
                this.breadcrumbs.splice(breadcrumb.index, 0, breadcrumb);
            } else {
                this.breadcrumbs.push(breadcrumb);
            }

            this.setBreadcrumbHeight();
        });

这是两个独立的可观察对象,我使用了延迟,但我知道这不是最好的做法,您建议如何做?

您不应该订阅第一个可观察对象,而是使用另一个操作符最终订阅第二个可观察对象。 您需要的运算符是mergemap或switchmap

编辑 你能试试这个吗

this.router.events
    .filter(event => event instanceof NavigationEnd)
    .startWith({})
    .pairwise()
    .tap((events: [NavigationEnd, NavigationEnd]) => {
        if (
            this.breadcrumbs.length > 0 &&
            events[0].url &&
            events[0].url.split("?")[0] === events[1].url.split("?")[0]
        ) {
            return;
        }
        let root: ActivatedRoute = this.activatedRoute.root;
        this.breadcrumbs = this.getBreadcrumbs(root);

        this.checkSetIsHomePage();
        this.setBreadcrumbHeight();
    })
    .switchMap(() => this.breadcrumbService.additionalBreadcrumbs)
    .takeUntil(this.destroy$)
    .subscribe(breadcrumb => {
        if (breadcrumb.index) {
            this.breadcrumbs.splice(breadcrumb.index, 0, breadcrumb);
        } else {
            this.breadcrumbs.push(breadcrumb);
        }

        this.setBreadcrumbHeight();
    });

这里您要做的是使用tap操作符在每次发射时操纵“this”,但您不会更改可观测值,您自己也不会发射一个。然后切换到第二个可观察对象,在第一个的每个发射上。

我想说,RXJS需要的操作符是

与直接订阅这两个观测值不同,您可能需要使用映射对它们进行管道传输,以执行所需的操作并最终对它们进行连接

const observable1 = this.router.events
        .filter(event => event instanceof NavigationEnd)
        .startWith({})
        .pairwise()
        .pipe(map((events: [NavigationEnd, NavigationEnd]) => {
            if (
                this.breadcrumbs.length > 0 &&
                events[0].url &&
                events[0].url.split("?")[0] === events[1].url.split("?")[0]
            ) {
                return;
            }
            let root: ActivatedRoute = this.activatedRoute.root;
            this.breadcrumbs = this.getBreadcrumbs(root);

            this.checkSetIsHomePage();
            this.setBreadcrumbHeight();
        }));

const observable2 =     this.breadcrumbService.additionalBreadcrumbs
        .takeUntil(this.destroy$)
        .pipe(map(breadcrumb => {
            if (breadcrumb.index) {
                this.breadcrumbs.splice(breadcrumb.index, 0, breadcrumb);
            } else {
                this.breadcrumbs.push(breadcrumb);
            }

            this.setBreadcrumbHeight();
        });

concat(observable1,observable2).subscribe()

我还没有测试过它,但我认为它应该可以工作

您可以使用finalize

this.router.events
    .filter(event => event instanceof NavigationEnd)
    .startWith({})
    .pairwise()
    .pipe(
        finalize(() => {

            this.breadcrumbService.additionalBreadcrumbs
                .takeUntil(this.destroy$)
                .subscribe(breadcrumb => {
                    if (breadcrumb.index) {
                        this.breadcrumbs.splice(breadcrumb.index, 0, breadcrumb);
                    } else {
                        this.breadcrumbs.push(breadcrumb);
                    }

                    this.setBreadcrumbHeight();
                });
        })
    )
    .subscribe((events: [NavigationEnd, NavigationEnd]) => {
        if (
            this.breadcrumbs.length > 0 &&
            events[0].url &&
            events[0].url.split("?")[0] === events[1].url.split("?")[0]
        ) {
            return;
        }
        let root: ActivatedRoute = this.activatedRoute.root;
        this.breadcrumbs = this.getBreadcrumbs(root);

        this.checkSetIsHomePage();
        this.setBreadcrumbHeight();
    });

我尝试了这种方法,但出于某种原因,它没有调用“observed2”。因为“observed1”应该在运行“observed2”时完成,所以有其他选择吗?这很奇怪,因为我已经测试过了,并且可以工作。请告诉我这是否也适用于你const Observable 1:Observable=of(console.log(“调用Observable 1函数”);const observe2:observeable=of(console.log(“调用observeable 2函数”);concat(observed1,observed2).subscribe(()=>console.log('firstaproach');observe1.pipe(switchMap(()=>{return observe2})).subscribe(()=>console.log('Second aproach')```为了运行finalize,第一个observable应该完成,所以它不会运行第二个observable,还有其他选择吗?你能澄清一下,你想什么时候订阅第二个observable吗?您的第一个Observable永远不会完成,但您在问题/标题中说,当第一个'is complete'/'完成时,您希望订阅第二个。@fridoo对,它在调用组件destroy时完成,但我希望第二个Observable始终在第一个Observable发出并在subscribe中运行完代码后发出,有没有办法做到这一点?这似乎是OP正在寻找的解决方案。您应该通过添加示例代码来改进您的答案。