typescript - Angular/RxJS - มี pipe ของ RxJS สำหรับ stream ที่เริ่มต้นหรือไม่?
ฉันกำลังพยายามสร้างวิธีการในการแสดงและซ่อนหน้าจอการโหลดอย่างไดนามิกเมื่อกำลังแก้ไขสตรีมบางอย่าง
นี่คือโค้ดปัจจุบันของฉัน:
this.requestService
.get<Checkout>(`check/${orderNumber}`)
.pipe(
tap(() => this.startLoading()), //i think this isnt the right way to use this pipe
finalize(() => this.endLoading())
)
.subscribe(
data => {
data.orderNumber = orderNumber
this.checkout.next(data)
},
error => {
this.notification.warning(error)
}
)
ผลลัพธ์ที่คาดหวังคือเมื่อสตรีมของฉันเริ่ม ให้แสดงหน้าจอการโหลดด้วย startLoading() และเมื่อการทำงานเสร็จสิ้น ให้ซ่อนการโหลดโดยใช้ endLoading()
โค้ดที่ฉันกำลังทำงานอยู่:
this.startLoading() //basically calling function before i create the stream
this.requestService
.get<Checkout>(`check/${orderNumber}`)
.pipe(
finalize(() => this.endLoading())
)
.subscribe(
data => {
data.orderNumber = orderNumber
this.checkout.next(data)
},
error => {
this.notification.warning(error)
}
)
ฉันกำลังใช้ท่อ tap นี้อย่างถูกต้องหรือไม่? มีท่ออื่นที่จะช่วยแก้ปัญหานี้ได้ดีกว่านี้หรือไม่?
วิธีที่ดีที่สุดในการทำสิ่งนี้โดยใช้ RxJS คืออะไร?
คำตอบ #1
ในตัวอย่างแรกของคุณ ท่อของคุณทำงานหลังจากที่คำขอ http ของคุณเสร็จสิ้นแล้ว
สุดท้ายแล้ว คุณก็แค่เรียก this.startLoading() ก่อนที่คุณจะเริ่มการร้องขอ http
this.startLoading();
this.requestService.get<Checkout>(`check/${orderNumber}`).pipe(
finalize(() => this.endLoading())
).subscribe(() => {
});
ถ้าคุณ จริงๆ ต้องการเรียก this.startLoading() ใน pipe คุณสามารถเรียกมันได้ก่อนที่คำขอ http จะเริ่มโดยการเริ่มจาก observable ของคุณเอง:
return of(null).pipe(
tap(() => this.startLoading()),
concatMap(() => this.requestService.get<Checkout>(`check/${orderNumber}`)),
finalize(() => this.endLoading())
).subscribe(() => {
});
แต่จริงๆ แล้ว การทำแบบนั้นก็แทบไม่มีความหมายอะไร
ดังนั้นไวยากรณ์ tap ของคุณถูกต้อง เพียงแต่มันไม่ได้ทำงานเมื่อคุณคิดว่ามันควรจะทำงาน
คำตอบ #2
ถ้าคุณต้องการทำเอฟเฟกต์ข้างเคียงกับการสมัครใช้งาน observable ทุกครั้ง คุณสามารถห่อแหล่งข้อมูลด้วย defer() ได้
import { defer } from 'rxjs';
...
defer(() => {
this.startLoading();
return this.requestService.get<Checkout>(`check/${orderNumber}`);
}).pipe(
finalize(() => this.endLoading())
)
.subscribe(...);
