--- แก้ไข 4 - แหล่งข้อมูลเพิ่มเติม (2018/09/01)
ในตอนล่าสุดของการผจญภัยในเชิงมุมเบนเลชและวอร์ดเบลล์หารือเกี่ยวกับประเด็นต่างๆว่าจะยกเลิกการสมัครสมาชิกในองค์ประกอบอย่างไร การสนทนาเริ่มต้นที่ประมาณ 1:05:30 น.
วอร์ดกล่าวright now there's an awful takeUntil dance that takes a lot of machinery
และ Shai Reznik Angular handles some of the subscriptions like http and routing
กล่าว
ในการตอบกลับเบ็นกล่าวว่าขณะนี้มีการหารือกันเพื่อให้ Observables สามารถเชื่อมต่อกับวงจรชีวิตขององค์ประกอบเชิงมุมและ Ward แนะนำให้สังเกตเหตุการณ์รอบการทำงานที่องค์ประกอบสามารถสมัครสมาชิกเพื่อให้ทราบว่าเมื่อใดที่ Observables ได้รับการดูแลในฐานะองค์ประกอบภายใน
ที่กล่าวว่าเราต้องการโซลูชันเป็นส่วนใหญ่ดังนั้นนี่คือแหล่งข้อมูลอื่น
คำแนะนำสำหรับtakeUntil()
รูปแบบจากสมาชิกในทีมหลักของ RxJs Nicholas Jamieson และกฎ tslint เพื่อช่วยบังคับใช้ https://ncjamieson.com/avoiding-takeuntil-leaks/
แพคเกจ NPM น้ำหนักเบาที่ exposes ผู้ประกอบการสังเกตที่ใช้อินสแตนซ์ส่วนประกอบ ( this
) ngOnDestroy
เป็นพารามิเตอร์โดยอัตโนมัติและการยกเลิกการสมัครในช่วง
https://github.com/NetanelBasal/ngx-take-until-destroy
อีกรูปแบบหนึ่งของด้านบนที่มีการยศาสตร์ที่ดีขึ้นเล็กน้อยถ้าคุณไม่ได้สร้าง AOT (แต่เราควรจะทำ AOT ตอนนี้)
https://github.com/smnbbrv/ngx-rx-collector
คำสั่งที่กำหนดเอง*ngSubscribe
ที่ทำงานเหมือนไปป์ async แต่สร้างมุมมองแบบฝังในแม่แบบของคุณเพื่อให้คุณสามารถอ้างถึงค่า 'ไม่ได้ห่อ' ตลอดทั้งแม่แบบของคุณ
https://netbasal.com/diy-subscription-handling-directive-in-angular-c8f6e762697f
ฉันพูดถึงในความคิดเห็นในบล็อกของนิโคลัสที่มากกว่าการใช้takeUntil()
อาจเป็นสัญญาณว่าองค์ประกอบของคุณพยายามที่จะทำมากเกินไปและแยกชิ้นส่วนที่มีอยู่ของคุณลงในคุณสมบัติและPresentationalส่วนประกอบควรได้รับการพิจารณา จากนั้นคุณสามารถ| async
สังเกตเห็นได้จากองค์ประกอบคุณสมบัติในInput
องค์ประกอบปัจจุบันซึ่งหมายความว่าไม่จำเป็นต้องสมัครสมาชิกใด ๆ อ่านเพิ่มเติมเกี่ยวกับวิธีการนี้ได้ที่นี่
--- แก้ไข 3 - ทางออก 'เป็นทางการ' (2017/04/52)
ฉันได้พูดคุยกับ Ward Bell เกี่ยวกับคำถามนี้ที่ NGConf (ฉันยังแสดงให้เขาเห็นคำตอบนี้ซึ่งเขาพูดถูกต้อง) แต่เขาบอกกับฉันว่าทีมเอกสารสำหรับ Angular มีวิธีแก้ปัญหาสำหรับคำถามนี้ที่ไม่ได้เผยแพร่ (แม้ว่าพวกเขากำลังทำงาน ) เขายังบอกฉันว่าฉันสามารถอัพเดตคำตอบ SO ของฉันด้วยคำแนะนำอย่างเป็นทางการที่กำลังจะมาถึง
ทางออกที่เราทุกคนควรใช้ในอนาคตคือการเพิ่มprivate ngUnsubscribe = new Subject();
เขตข้อมูลให้กับส่วนประกอบทั้งหมดที่มีการ.subscribe()
เรียกไปยังObservable
s ภายในรหัสชั้นเรียนของพวกเขา
จากนั้นเราโทรthis.ngUnsubscribe.next(); this.ngUnsubscribe.complete();
ในngOnDestroy()
วิธีการของเรา
ซอสลับ (ตามที่ระบุไว้แล้วโดย@metamaker ) คือการโทรtakeUntil(this.ngUnsubscribe)
ก่อนการโทรแต่ละครั้งของเรา.subscribe()
ซึ่งจะรับประกันการสมัครสมาชิกทั้งหมดจะถูกล้างออกเมื่อส่วนประกอบถูกทำลาย
ตัวอย่าง:
import { Component, OnDestroy, OnInit } from '@angular/core';
// RxJs 6.x+ import paths
import { filter, startWith, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { BookService } from '../books.service';
@Component({
selector: 'app-books',
templateUrl: './books.component.html'
})
export class BooksComponent implements OnDestroy, OnInit {
private ngUnsubscribe = new Subject();
constructor(private booksService: BookService) { }
ngOnInit() {
this.booksService.getBooks()
.pipe(
startWith([]),
filter(books => books.length > 0),
takeUntil(this.ngUnsubscribe)
)
.subscribe(books => console.log(books));
this.booksService.getArchivedBooks()
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe(archivedBooks => console.log(archivedBooks));
}
ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
}
หมายเหตุ:มันเป็นสิ่งสำคัญที่จะเพิ่มtakeUntil
ผู้ประกอบการเป็นคนสุดท้ายเพื่อป้องกันการรั่วไหลด้วยสังเกตกลางในห่วงโซ่ผู้ประกอบการ
--- แก้ไข 2 (2016/12/28)
ที่มา 5
บทช่วยสอนเชิง Angular ตอนนี้ระบุถึงสิ่งต่อไปนี้: "เราเตอร์จัดการสิ่งที่สังเกตได้และให้การสมัครสมาชิกการแปลจะถูกล้างเมื่อส่วนประกอบถูกทำลายเพื่อป้องกันการรั่วไหลของหน่วยความจำดังนั้นเราจึงไม่จำเป็นต้องยกเลิกการสมัคร params เส้นทางสังเกตได้ " - Mark Rajcok
นี่คือการอภิปรายเกี่ยวกับปัญหา Github สำหรับเอกสารเชิงมุมเกี่ยวกับการสังเกตเราเตอร์ที่ Ward Bell ระบุว่าการชี้แจงทั้งหมดนี้อยู่ในผลงาน
--- แก้ไข 1
ที่มา 4
ในวิดีโอนี้จาก NgEurope Rob Wormald ยังบอกด้วยว่าคุณไม่จำเป็นต้องยกเลิกการสมัครรับข้อมูลจาก Router Observables นอกจากนี้เขายังกล่าวถึงhttp
การให้บริการและActivatedRoute.params
ในครั้งนี้วิดีโอจากพฤศจิกายน 2016
--- คำตอบเดิม
TLDR:
สำหรับคำถามนี้มี (2) ชนิดObservables
- ค่าจำกัดและค่าไม่ จำกัด
http
Observables
สร้างค่า จำกัด (1) และบางอย่างเช่น DOM event listener
Observables
สร้างค่าไม่สิ้นสุด
ถ้าคุณโทรsubscribe
(ไม่ได้ใช้ท่อ async) แล้วunsubscribe
จากการที่ไม่มีที่สิ้นสุด Observables
ไม่ต้องกังวลกับคนที่จำกัดRxJs
จะดูแลพวกเขา
ที่มา 1
ผมติดตามลงคำตอบจากร็อบ Wormald ในเชิงมุมของ Gitter ที่นี่
เขากล่าว (ฉันจัดระเบียบใหม่เพื่อความชัดเจนและเน้นเป็นของฉัน)
หากเป็นลำดับเดียว (เช่นคำขอ http) การล้างด้วยตนเองนั้นไม่จำเป็น (สมมติว่าคุณสมัครสมาชิกในคอนโทรลเลอร์ด้วยตนเอง)
ฉันควรจะพูดว่า "ถ้ามันเป็นลำดับที่สมบูรณ์ " (ซึ่งลำดับค่าเดียวคือ la http เป็นหนึ่ง)
ถ้าลำดับอนันต์มัน , คุณควรจะยกเลิกการเป็นสมาชิกที่ท่อ async ไม่สำหรับคุณ
นอกจากนี้เขากล่าวถึงในเรื่องนี้วิดีโอ YouTubeบน observables ว่าthey clean up after themselves
... ในบริบทของ observables ที่complete
(เช่นสัญญาที่สมบูรณ์เสมอเพราะพวกเขามักจะผลิต 1 คุ้มค่าและสิ้นสุด - เราไม่เคยกังวลเกี่ยวกับการยกเลิกจากสัญญาที่จะทำให้แน่ใจว่าพวกเขาทำความสะอาดxhr
เหตุการณ์ ผู้ฟังใช่ไหม?)
ที่มา 2
นอกจากนี้ในคู่มือ Rangle ไปที่ Angular 2 ที่อ่าน
ในกรณีส่วนใหญ่เราไม่จำเป็นต้องโทรหาวิธีการยกเลิกการสมัครอย่างชัดเจนเว้นแต่ว่าเราต้องการยกเลิกก่อนกำหนดหรือ Observable ของเรามีอายุการใช้งานนานกว่าการสมัครของเรา พฤติกรรมเริ่มต้นของโอเปอเรเตอร์ Observable คือการกำจัดการสมัครสมาชิกทันทีที่ข้อความ. comlete () หรือ .error () ถูกเผยแพร่ โปรดจำไว้ว่า RxJS ถูกออกแบบมาเพื่อใช้ใน "ไฟและลืม" แฟชั่นเกือบตลอดเวลา
วลีนี้our Observable has a longer lifespan than our subscription
ใช้เมื่อใด
มันจะใช้เมื่อการสมัครสมาชิกถูกสร้างขึ้นภายในองค์ประกอบที่ถูกทำลายก่อน (หรือไม่ 'ยาว' ก่อน) ความObservable
สมบูรณ์
ฉันอ่านสิ่งนี้เป็นความหมายถ้าเราสมัครรับhttp
คำขอหรือสิ่งที่สังเกตได้ที่ปล่อยออกมา 10 ค่าและองค์ประกอบของเราถูกทำลายก่อนที่http
คำขอนั้นจะส่งคืนหรือ 10 ค่านั้นถูกปล่อยออกมาเราก็ยังโอเค!
เมื่อคำขอกลับมาหรือค่าที่ 10 ถูกปล่อยออกมาในที่สุดก็Observable
จะเสร็จสมบูรณ์และทรัพยากรทั้งหมดจะถูกล้างออก
ที่มา 3
หากเราดูตัวอย่างจากคู่มือ Rangle เดียวกันเราจะเห็นว่าสิ่งSubscription
ที่route.params
ต้องทำคือไม่ต้องทำunsubscribe()
เพราะเราไม่รู้ว่าเมื่อใดparams
จะหยุดการเปลี่ยนแปลง (ปล่อยค่าใหม่)
องค์ประกอบที่จะถูกทำลายโดยการนำออกไปซึ่งในกรณี params เส้นทางมีแนวโน้มที่จะยังคงมีการเปลี่ยนแปลง (พวกเขาในทางเทคนิคอาจมีการเปลี่ยนแปลงจนกระทั่งปลาย app) completion
และทรัพยากรที่จัดสรรในการสมัครสมาชิกจะยังคงได้รับการจัดสรรเพราะมีไม่ได้รับการ
Subscription
ที่จะhttp-requests
สามารถปฏิเสธเช่นที่พวกเขาเพียงโทรครั้งเดียวแล้วที่พวกเขาเรียกonNext
แทนที่จะเรียกร้องซ้ำแล้วซ้ำอีกและไม่อาจเรียก(ไม่แน่ใจเกี่ยวกับที่ ... ) กันไปจากs ดังนั้นผมคิดว่าผู้ที่ควรจะเป็นonComplete
Router
onNext
onComplete
Observable
Event
unsubscribed