--- แก้ไข 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()เรียกไปยังObservables ภายในรหัสชั้นเรียนของพวกเขา
จากนั้นเราโทร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 ดังนั้นผมคิดว่าผู้ที่ควรจะเป็นonCompleteRouteronNextonCompleteObservableEventunsubscribed