gpt4 book ai didi

javascript - Angular 5,rxjs-仅当它处于运行中间时才等待 observable 完成,然后再运行另一个进程

转载 作者:行者123 更新时间:2023-11-30 19:49:19 28 4
gpt4 key购买 nike

我的主要组件中有一个 3 秒计时器。在计时器内我执行 http 调用-

    constructor(){
this.timer = timer(3000, 3000);
this.timerObservable = this.timer.subscribe(x => {
this.http.get(URL).subscribe(()=>{
//DO SOMETHING
});
});

}

在另一个组件中,我有一个按钮,假设执行不同的 http 调用,按下按钮调用 sumbit 函数-

        submit(){
this.http.get("/sumbitForm").subscribe(()=> {
//DO SOMETHING
})
}

当用户单击按钮时,如果计时器正在处理(其中的 http 已被调用但尚未解析),我想在对按钮执行 http 调用之前等待,直到它解析,但是如果timer is not in process(上次调用的时间还没有过去)我想立即执行。

我认为 forkJoin 和 concat 在这里不相关(这是一个计时器,而不是一个“常规”订阅,我想以任何一种方式等待它的执行)而且我找不到一个很好的方法来做到这一点,任何想法?

最佳答案

您需要在两个组件之间共享一些信息,即轮询请求何时进行以及何时不进行。您应该为此使用服务。将您的 http 请求逻辑移动到服务而不是直接在组件中使用 HttpClient 也是一种很好的做法。这允许您在一个地方进行一般错误处理。我们称此服务为 ApiService。

API服务

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, BehaviorSubject, interval } from 'rxjs';
import { switchMap, tap } from 'rxjs/operators';

@Injectable({ providedIn: 'root' })
export class ApiService {
// Use a BehaviorSubject to notify listeners about ongoing polling requests.
// A BahaviorSubject always has a current value that late subscribers will
// receive immediately upon subscribing
private pollRequestInProgress = new BehaviorSubject<boolean>(false);
// Share this BehaviorSubject as an Observable
public pollRequestInProgress$ = pollRequestInProgress.asObservable();

constructor(private http: HttpClient)

doPoll(url: string): Observable<any> {
return interval(3000).pipe( // interval(3000) is equivalent to timer(3000, 3000)
tap(_ => pollRequestInProgress.next(true)), // notify that a poll request is about to happen
switchMap(_ => this.http.get(url)), // do your poll request
tap(_ => pollRequestInProgress.next(false)) // notify that your poll request ended
);
}
}

主要组件

这是您要从中开始轮询的组件。

private destroy$: Subject<void> = new Subject<void>();

constructor(private apiService: ApiService) {}

// move logic to ngOnInit instead of constructor
ngOnInit() {
// subscribe and thereby start the polling
this.apiService.doPoll(URL).pipe(takeUntil(this.destroy$))
.subscribe(pollResponse => {
//DO SOMETHING
});
}

ngOnDestroy() {
// unsubscribe when the Component gets destroyed.
this.destroy$.next();
this.destroy$.complete();
}

特征组件

这是您要在单击按钮时执行 http 请求的组件。

constructor(private http: HttpClient, private apiService: apiService) {}

submit() {
// Listen to whether a polling request is currently in progress.
// We will immediately receive a value upon subscribing here, because we used
// a BehaviorSubject as the underlying source.
this.apiService.pollRequestInProgress$.pipe(
// Emit the first item that tells you that no polling request is in progress.
// i.e. let the first 'requestInProgress === false' through but not any
// other items before or after.
first(requestInProgress => !requestInProgress),
// If no polling request is in progress, switch to the http request you want
// to perform
switchMap(this.http.get("/sumbitForm")) // <-- consider moving this http.get to your ApiService aswell
).subscribe(httpResponse => {
// you've got your http response here
});
// you don't have to unsubscribe here as first and http.get both complete
// and thus unsubscribe automatically
}

在此处查看上面代码逻辑的一个简单示例:https://stackblitz.com/edit/rxjs-t4hjcr

关于javascript - Angular 5,rxjs-仅当它处于运行中间时才等待 observable 完成,然后再运行另一个进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54629934/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com