微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何延迟评估合并的 observable,即在使用 merge() (RxJs v6) 时单击按钮?

如何解决如何延迟评估合并的 observable,即在使用 merge() (RxJs v6) 时单击按钮?

我有一个合并的可观察流,

const nextClickHandler$ = merge(doA$,dob$,doC$),

do A$/B$/C$ 是产生 HTTPRequest 或执行一些副作用的 observable,它们在一些互斥的条件下运行,其中 doA$/dob$/doC$ 处于活动状态并执行网络调用/副作用。>

用例是,在单击下一步按钮时,执行 A/B/C,如果我在单击下一步之前订阅它,我将面临如何订阅此合并 observable 的问题,即

ngOnInit(){
    this.nextClickHandler$.subscribe()
}

这将急切地评估那些相互排斥的条件并执行,甚至无需单击下一步,

我尝试通过点击 goForward 订阅

 goForward(): void {
        if (this.getCurrentStep() == 1) {
            if (this.validateForm()) {\
                //performs side-effects for either A$/B$/C$
                this.nextClickHandler$.subscribe();  
            }
            return;
        }

但是现在,当我再次上 Step I 时,它不会等待下一个的点击,因为它是长期订阅,它只是急切地执行行为,这不是我想要的,我想要它们仅在单击下一步时延迟执行,我尝试了 take(1) 但这并不能解决问题,我该如何实现?

解决方法

如果您不喜欢创建多个订阅变量,

switchMap() 是一个很好的例子,但如果您想继续使用 merge()mergeMap,请尝试使用 takeUntil() 运算符。您无需每次都创建订阅变量。

你只创建一次,销毁一次,但你可以在同一个页面代码中多次使用它。

// Step-1: Create a destroy variable
destroy$: Subject<any> = new Subject();

// Step-2: Use it how many times you want

obs1$.pipe(takeUntil(this.destroy$)).subscribe();
obs2$.pipe(takeUntil(this.destroy$)).subscribe();
obs3$.pipe(takeUntil(this.destroy$)).subscribe();
.
.
.
so on... 

// Step-3 : Destroy the subject

ngOnDestroy() {
  this.destroy$.next();
  this.destroy$.complete();
}

如果你想合并 observables,你也可以使用 combineLatest() 操作符,你可以一次订阅多个 observables。像这样:

combineLatest(obs1$,obs2$,obs3$)
   .takeUntil(this.destroy$)
   .subscribe(([obs1Data,obs2Data,obs3Data]) => {})
,

您可以尝试从按钮的点击事件创建一个 Observable,使用 fromEvent:

 <button #sbtn>
      Subscribe
    </button>

 @ViewChild('sbtn',{ static: true }) sbtn: ElementRef;
 this.clickBtnEvent$ = fromEvent(this.sbtn.nativeElement,'click');

而不是在 init 上(或在 view init 之后)订阅那个 Observable:

this.clickBtnEvent$.pipe(
  mergeMap(() => nextClickHandler$)
).subscribe( /* some logic*/);

这个 Observable 只有在你点击按钮时才会发出,实际上每次点击它。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。