ฉันต้องการสร้างการสมัครรับข้อมูลObservable
ที่จะถูกกำจัดทันทีเมื่อมีการโทรครั้งแรก
มีบางอย่างเช่น:
observable.subscribeOnce(func);
กรณีการใช้งานของฉันฉันกำลังสร้างการสมัครสมาชิกในตัวจัดการเส้นทางด่วนและการสมัครจะถูกเรียกหลายครั้งต่อคำขอ
ฉันต้องการสร้างการสมัครรับข้อมูลObservable
ที่จะถูกกำจัดทันทีเมื่อมีการโทรครั้งแรก
มีบางอย่างเช่น:
observable.subscribeOnce(func);
กรณีการใช้งานของฉันฉันกำลังสร้างการสมัครสมาชิกในตัวจัดการเส้นทางด่วนและการสมัครจะถูกเรียกหลายครั้งต่อคำขอ
คำตอบ:
ไม่แน่ใจ 100% เกี่ยวกับสิ่งที่คุณต้องการ แต่ถ้าคุณต้องการสังเกตค่าแรกให้ใช้อย่างใดอย่างหนึ่งfirst()
หรือtake(1)
:
observable.first().subscribe(func);
หมายเหตุ: .take(1)
และ.first()
ทั้งสองอย่างจะยกเลิกการเป็นสมาชิกโดยอัตโนมัติเมื่อตรงตามเงื่อนไข
import { first } from 'rxjs/operators'
observable
.pipe(first())
.subscribe(func);
observable.pipe(first()).subscribe(func)
ที่มาจากfirst
rxjs/operators
RxJS มีเอกสารที่ดีที่สุดที่ฉันเคยเจอ การติดตามลิงก์ร้องจะนำคุณไปสู่กรณีการใช้งานการแมปตารางที่เป็นประโยชน์อย่างยิ่งแก่ผู้ประกอบการ ยกตัวอย่างเช่นภายใต้ "ฉันต้องการที่จะใช้ค่าแรก" กรณีใช้เป็นสามผู้ประกอบการ: first
, และfirstOrDefault
sample
หมายเหตุหากลำดับที่สังเกตได้เสร็จสมบูรณ์โดยไม่มีการแจ้งเตือนfirst
ผู้ประกอบการจะแจ้งให้สมาชิกทราบว่ามีข้อผิดพลาดในขณะที่firstOrDefault
ผู้ดำเนินการให้ค่าเริ่มต้นแก่สมาชิก
หากคุณต้องการเรียกใช้ Observable เพียงครั้งเดียวก็หมายความว่าคุณจะไม่รอกระแสข้อมูลจากมัน ดังนั้นการใช้toPromise()
แทนที่จะsubscribe()
เพียงพอในกรณีของคุณเนื่องจากtoPromise()
ไม่จำเป็นต้องยกเลิกการสมัคร
await
promise
เพื่อเสริม@ คำตอบของแบรนดอนใช้first()
หรือชอบนอกจากนี้ยังเป็นสิ่งจำเป็นสำหรับการปรับปรุงบนพื้นฐานของBehaviorSubject
Observable
ตัวอย่าง (ยังไม่ได้ทดสอบ):
var subject = new BehaviorSubject({1:'apple',2:'banana'});
var observable = subject.asObservable();
observable
.pipe(
first(), // <-- Ensures no stack overflow
flatMap(function(obj) {
obj[3] = 'pear';
return of(obj);
})
)
.subscribe(function(obj) {
subject.next(obj);
});
การขยายคำตอบที่น่าอัศจรรย์ของ M Fuat NUROĞLUในการแปลงคำสัญญาที่สังเกตได้เป็นนี่เป็นรุ่นที่สะดวกมาก
const value = await observable.toPromise();
console.log(value)
ความงามของสิ่งนี้คือเราสามารถใช้ค่านั้นเหมือนตัวแปรปกติโดยไม่ต้องแนะนำบล็อกที่ซ้อนกันอีก!
สิ่งนี้มีประโยชน์อย่างยิ่งเมื่อคุณต้องการรับค่าหลายค่าจากการสังเกตได้หลายค่า เรียบร้อยและสะอาด
const content = await contentObservable.toPromise();
const isAuthenticated = await isAuthenticatedObservable.toPromise();
if(isAuthenticated){
service.foo(content)
}
แน่นอนคุณจะต้องทำให้ฟังก์ชั่นที่มีของคุณasync
ถ้าคุณจะไปกับเส้นทางนี้ คุณสามารถทำ.then
ตามสัญญาได้หากคุณไม่ต้องการให้ฟังก์ชั่นที่มีอยู่เป็นแบบอะซิงก์
ฉันไม่แน่ใจว่ามีการแลกเปลี่ยนกับวิธีการนี้หรือไม่โปรดแจ้งให้เราทราบในความคิดเห็นเพื่อที่เราจะได้ทราบ
ป.ล. ถ้าคุณชอบคำตอบนี้อย่าลืมตอบคำถามของ M Fuat NUROĞLUด้วย :)
ฉันมีคำถามที่คล้ายกัน
ด้านล่างนี้ถูกเรียกใช้ในภายหลังจากผู้เปลี่ยนสถานะที่แตกต่างกัน อย่างที่ฉันไม่ต้องการ
function foo() {
// this was called many times which was not needed
observable.subscribe(func);
changeObservableState("new value");
}
ฉันตัดสินใจลองunsubscribe()
สมัครหลังจากด้านล่าง
function foo() {
// this was called ONE TIME
observable.subscribe(func).unsubscribe();
changeObservableState("new value");
}
subscribe(func).unsubscribe();
subscribeOnce(func)
เป็นเหมือน
ฉันหวังว่าจะช่วยคุณเช่นกัน