จำเป็นหรือไม่ที่จะยกเลิกการเป็นสมาชิกจากสิ่งที่สังเกตได้ที่สร้างโดยวิธี Http?


211

คุณต้องการยกเลิกการสมัครจากการโทร http ของ Angular 2 เพื่อป้องกันการรั่วไหลของหน่วยความจำหรือไม่?

 fetchFilm(index) {
        var sub = this._http.get(`http://example.com`)
            .map(result => result.json())
            .map(json => {
                dispatch(this.receiveFilm(json));
            })
            .subscribe(e=>sub.unsubscribe());
            ...

1
เป็นไปได้ซ้ำของการป้องกันการรั่วไหล
Eric Martinez

1
ดูstackoverflow.com/questions/34461842/… (และความเห็นเช่นกัน)
Eric Martinez

คำตอบ:


253

ดังนั้นคำตอบคือไม่คุณทำไม่ได้ Ng2จะทำความสะอาดมันเอง

แหล่งบริการ Http จากแหล่งแบ็กเอนด์ Http XHR ของ Angular:

ป้อนคำอธิบายรูปภาพที่นี่

สังเกตว่ามันทำงานอย่างไรcomplete()หลังจากได้ผลลัพธ์ ซึ่งหมายความว่าจะเป็นการยกเลิกการเป็นสมาชิกเมื่อเสร็จสิ้น ดังนั้นคุณไม่จำเป็นต้องทำด้วยตัวเอง

นี่คือการทดสอบเพื่อตรวจสอบความถูกต้อง:

  fetchFilms() {
    return (dispatch) => {
        dispatch(this.requestFilms());

        let observer = this._http.get(`${BASE_URL}`)
            .map(result => result.json())
            .map(json => {
                dispatch(this.receiveFilms(json.results));
                dispatch(this.receiveNumberOfFilms(json.count));
                console.log("2 isUnsubscribed",observer.isUnsubscribed);
                window.setTimeout(() => {
                  console.log("3 isUnsubscribed",observer.isUnsubscribed);
                },10);
            })
            .subscribe();
        console.log("1 isUnsubscribed",observer.isUnsubscribed);
    };
}

ตามที่คาดไว้คุณจะเห็นว่ามีการยกเลิกการสมัครรับข้อมูลโดยอัตโนมัติเสมอหลังจากได้รับผลลัพธ์และจบด้วยตัวดำเนินการที่สังเกตได้ สิ่งนี้เกิดขึ้นในการหมดเวลา (# 3) เพื่อให้เราสามารถตรวจสอบสถานะของสิ่งที่สังเกตได้เมื่อทำเสร็จแล้ว

และผลที่ได้

ป้อนคำอธิบายรูปภาพที่นี่

ดังนั้นจะไม่มีการรั่วไหลเนื่องจากNg2การยกเลิกการสมัครอัตโนมัติ!

ยินดีที่จะพูดถึง: นี่Observableคือการจัดหมวดหมู่เป็นfiniteในทางตรงกันข้ามกับinfinite Observableซึ่งเป็นกระแสข้อมูลที่ไม่มีที่สิ้นสุดสามารถถูกปล่อยออกมาเช่น DOMclickฟังตัวอย่างเช่น

ขอบคุณ @rubyboy สำหรับความช่วยเหลือในเรื่องนี้


17
เกิดอะไรขึ้นในกรณีที่ผู้ใช้ออกจากหน้าเว็บก่อนที่จะมีการตอบสนองหรือหากไม่เคยมีการตอบสนองก่อนที่ผู้ใช้จะออกจากมุมมอง นั่นจะไม่ทำให้เกิดการรั่วไหลหรือไม่?
Thibs

1
ฉันต้องการทราบข้อมูลด้านบนด้วย
1984

4
@ 1984 คำตอบคือเสมอ UNSUBSCRIBE คำตอบนี้ผิดอย่างสิ้นเชิงกับเหตุผลที่เกิดขึ้นในความคิดเห็นนี้ ผู้ใช้ที่ออกไปคือลิงค์หน่วยความจำ นอกจากนี้หากรหัสในการสมัครรับข้อมูลรันหลังจากผู้ใช้ออกไปอาจทำให้เกิดข้อผิดพลาด / มีผลข้างเคียงที่ไม่คาดคิด ฉันมักจะใช้ takeWhile (() => this.componentActive) กับสิ่งที่สังเกตได้ทั้งหมดและตั้งค่า this.componentActive = false ใน ngOnDestroy เพื่อล้างสิ่งที่สังเกตได้ทั้งหมดในองค์ประกอบ
Lenny

4
ตัวอย่างที่แสดงที่นี่ครอบคลุมถึง api ส่วนตัวเชิงมุมลึก ด้วย API ส่วนตัวอื่น ๆ ก็สามารถเปลี่ยนแปลงได้ด้วยการอัพเกรดโดยไม่ต้องแจ้งให้ทราบล่วงหน้า Rule of thumb คือ: หากเอกสารไม่เป็นทางการอย่าตั้งสมมติฐานใด ๆ ตัวอย่างเช่น AsynPipe มีเอกสารที่ชัดเจนว่าจะสมัคร / ยกเลิกการสมัครโดยอัตโนมัติสำหรับคุณ เอกสาร HttpClient ไม่ได้พูดถึงสิ่งใด
YoussefTaghlabi

1
@YoussefTaghlabi, FYI, เอกสารเชิงมุมอย่างเป็นทางการ ( angular.io/guide/http ) ไม่พูดถึง: "AsyncPipe สมัครสมาชิก (และยกเลิกการสมัคร) ให้คุณอัตโนมัติ" ดังนั้นมันเป็นเอกสารอย่างเป็นทางการแน่นอน
Hudgi

96

คุณกำลังพูดถึงคนอะไร !!!

ตกลงดังนั้นมีสองเหตุผลในการยกเลิกการสมัครจากสิ่งที่สังเกตได้ ดูเหมือนจะไม่มีใครพูดถึงเหตุผลที่สองที่สำคัญมาก!

1) ล้างทรัพยากร อย่างที่คนอื่น ๆ บอกว่านี่เป็นปัญหาเล็กน้อยสำหรับ HTTP observables มันจะทำความสะอาดตัวเอง

2) ป้องกันไม่ให้subscribeตัวจัดการทำงาน

(สำหรับ HTTP สิ่งนี้จะยกเลิกคำขอในเบราว์เซอร์ด้วยเช่นกันดังนั้นจึงไม่ต้องเสียเวลาอ่านคำตอบ

ความเกี่ยวข้องของหมายเลข 2 จะขึ้นอยู่กับสิ่งที่ตัวจัดการการสมัครของคุณทำ:

หากsubscribe()ฟังก์ชันตัวจัดการของคุณมีผลข้างเคียงใด ๆ ที่ไม่พึงประสงค์หากการโทรใด ๆ ที่ถูกปิดหรือถูกกำจัดคุณต้องยกเลิกการสมัคร (หรือเพิ่มตรรกะตามเงื่อนไข) เพื่อป้องกันไม่ให้ถูกเรียกใช้

พิจารณาบางกรณี:

1) แบบฟอร์มเข้าสู่ระบบ คุณป้อนชื่อผู้ใช้และรหัสผ่านและคลิก 'เข้าสู่ระบบ' ถ้าเซิร์ฟเวอร์ช้าและคุณตัดสินใจที่จะกดปุ่ม Escape เพื่อปิดกล่องโต้ตอบ? คุณอาจจะสมมติว่าคุณไม่ได้เข้าสู่ระบบ แต่หากคำขอ http กลับมาหลังจากที่คุณกดหลบหนีจากนั้นคุณจะยังคงดำเนินการตามตรรกะที่คุณมี ซึ่งอาจส่งผลให้มีการเปลี่ยนเส้นทางไปยังหน้าบัญชีคุกกี้การเข้าสู่ระบบที่ไม่ต้องการหรือการตั้งค่าตัวแปรโทเค็น นี่อาจไม่ใช่สิ่งที่ผู้ใช้คาดหวัง

2) ฟอร์ม 'ส่งอีเมล'

หากว่า subscribeตัวจัดการสำหรับ 'sendEmail' ทำบางสิ่งเช่นเรียกภาพเคลื่อนไหว 'อีเมลของคุณถูกส่งไป' ถ่ายโอนคุณไปยังหน้าอื่นหรือพยายามเข้าถึงสิ่งที่ถูกกำจัดคุณอาจได้รับการยกเว้นหรือพฤติกรรมที่ไม่พึงประสงค์

นอกจากนี้ระวังอย่าถือว่าunsubscribe()หมายถึง 'ยกเลิก' เมื่อข้อความ HTTP อยู่ในระหว่างการบินunsubscribe()จะไม่ยกเลิกการร้องขอ HTTP หากมีข้อความมาถึงเซิร์ฟเวอร์ของคุณแล้ว มันจะยกเลิกการตอบกลับที่กลับมาหาคุณเท่านั้น และอีเมลอาจถูกส่งไป

หากคุณสร้างการสมัครสมาชิกเพื่อส่งอีเมลโดยตรงภายในคอมโพเนนต์ UI คุณอาจต้องการยกเลิกการสมัคร แต่ถ้าอีเมลถูกส่งโดยบริการที่ไม่ได้รวมศูนย์จาก UI คุณอาจไม่จำเป็นต้องทำ

3) ส่วนประกอบเชิงมุมที่ถูกทำลาย / ปิด http observables ใด ๆ ที่ยังคงทำงานอยู่ในเวลานั้นจะเสร็จสมบูรณ์และใช้ตรรกะของพวกเขาจนกว่าคุณจะยกเลิกการเป็นสมาชิกonDestroy()ยังคงทำงานในเวลาที่จะเสร็จสมบูรณ์และใช้ตรรกะของพวกเขาจนกว่าคุณจะยกเลิกการเป็นสมาชิกใน ไม่ว่าผลที่ตามมาจะไม่สำคัญหรือไม่นั้นขึ้นอยู่กับสิ่งที่คุณทำในตัวจัดการการสมัครรับข้อมูล หากคุณพยายามอัปเดตสิ่งที่ไม่มีอยู่อีกต่อไปคุณอาจได้รับข้อผิดพลาด

บางครั้งคุณอาจมีการกระทำบางอย่างที่คุณต้องการหากมีการกำจัดองค์ประกอบและบางอย่างที่คุณไม่ต้องการ ตัวอย่างเช่นคุณอาจมีเสียง 'swoosh' สำหรับอีเมลที่ส่ง คุณอาจต้องการให้สิ่งนี้เล่นแม้ว่าจะปิดองค์ประกอบไปแล้ว แต่ถ้าคุณพยายามเรียกใช้แอนิเมชันในองค์ประกอบมันจะล้มเหลว ในกรณีนั้นตรรกะเพิ่มเติมที่มีเงื่อนไขภายในการสมัครสมาชิกจะเป็นวิธีแก้ปัญหา - และคุณไม่ต้องการยกเลิกการสมัคร http ที่สังเกตได้

ดังนั้นในการตอบคำถามจริงคุณไม่จำเป็นต้องทำเพื่อหลีกเลี่ยงการรั่วไหลของหน่วยความจำ แต่คุณต้องทำ (บ่อยครั้ง) เพื่อหลีกเลี่ยงผลข้างเคียงที่ไม่พึงประสงค์ที่เกิดจากการเรียกใช้โค้ดที่อาจทำให้เกิดข้อยกเว้นหรือทำให้สถานะแอปพลิเคชันของคุณเสียหาย

คำแนะนำ: กระบวนการSubscriptionมีclosedคุณสมบัติบูลีนที่อาจมีประโยชน์ในกรณีขั้นสูง สำหรับ HTTP นี้จะถูกตั้งค่าเมื่อมันเสร็จสมบูรณ์ ในเชิงมุมอาจมีประโยชน์ในบางสถานการณ์ในการตั้งค่า_isDestroyedคุณสมบัติngDestroyที่subscribeตัวจัดการของคุณสามารถตรวจสอบได้

เคล็ดลับที่ 2: หากจัดการกับการสมัครรับข้อมูลหลายรายการคุณสามารถสร้างnew Subscription()วัตถุแบบ ad-hoc และadd(...)การสมัครรับข้อมูลอื่น ๆ ได้ดังนั้นเมื่อคุณยกเลิกการสมัครสมาชิกหลักรายการนั้นจะเป็นการยกเลิกการสมัครรับข้อมูลเพิ่มทั้งหมด


2
นอกจากนี้โปรดทราบว่าหากคุณมีบริการที่ส่งคืน http overvable แบบดิบและคุณไปป์ก่อนที่จะสมัครแล้วคุณจะต้องยกเลิกการสมัครจากขั้นตอนสุดท้ายที่สามารถสังเกตได้ไม่ใช่ http http พื้นฐานที่สามารถสังเกตได้ ในความเป็นจริงคุณจะไม่ได้สมัครสมาชิกกับ http โดยตรงเพื่อให้คุณไม่ได้
Simon_Weaver

แม้ว่าการยกเลิกการสมัครจะยกเลิกการร้องขอของเบราว์เซอร์ แต่เซิร์ฟเวอร์ยังคงทำตามคำขอ มีวิธีที่จะทำให้เซิร์ฟเวอร์ใกล้ชิดกับการยกเลิกการทำงานด้วยหรือไม่? ฉันส่งคำขอ HTTP อย่างรวดเร็วซึ่งส่วนใหญ่จะถูกยกเลิกโดยการยกเลิกการสมัคร แต่เซิร์ฟเวอร์ยังคงทำงานตามคำขอที่ถูกยกเลิกโดยลูกค้าทำให้การร้องขอถูกต้องตามกฎหมายรอ
บาลา

@bala คุณต้องหากลไกของตัวเองมาทำสิ่งนี้ - ซึ่งไม่มีส่วนเกี่ยวข้องกับ RxJS ตัวอย่างเช่นคุณอาจใส่คำขอลงในตารางและเรียกใช้หลังจาก 5 วินาทีในพื้นหลังหากสิ่งที่จำเป็นในการยกเลิกคุณจะลบหรือตั้งค่าสถานะในแถวเก่าที่จะหยุดพวกเขาดำเนินการ ทั้งหมดจะขึ้นอยู่กับว่าใบสมัครของคุณคืออะไร อย่างไรก็ตามเนื่องจากคุณระบุว่าเซิร์ฟเวอร์กำลังปิดกั้นอาจมีการกำหนดค่าให้อนุญาตเพียงหนึ่งครั้งต่อครั้ง - แต่จะขึ้นอยู่กับสิ่งที่คุณกำลังใช้อีกครั้ง
Simon_Weaver

🔥🔥🔥เคล็ดลับ 2 - เป็น PRO-TIP 🔥🔥🔥สำหรับทุกคนที่ต้องการยกเลิกการสมัครรับข้อมูลหลายรายการโดยการเรียกเพียงฟังก์ชั่นเดียว เพิ่มโดยใช้. add () วิธีการและกว่า. unsubscribe () ใน ngDestroy
abhay tripathi

23

การเรียกใช้unsubscribeเมธอดเป็นการยกเลิกคำร้องขอ HTTP ที่กำลังดำเนินอยู่เนื่องจากเมธอดนี้เรียกใช้เมธอดabortXHR และลบการรับฟังเหตุการณ์การโหลดและข้อผิดพลาด:

// From the XHRConnection class
return () => {
  _xhr.removeEventListener('load', onLoad);
  _xhr.removeEventListener('error', onError);
  _xhr.abort();
};

ที่กล่าวว่าunsubscribeเอาผู้ฟังออก ... ดังนั้นอาจเป็นความคิดที่ดี แต่ฉันไม่คิดว่ามันจำเป็นสำหรับการร้องขอเพียงครั้งเดียว ;-)

หวังว่าจะช่วยให้คุณ Thierry


: | นั่นไร้สาระ: | ฉันกำลังมองหาวิธีที่จะหยุด ... แต่ฉันสงสัยและถ้าฉันเป็นรหัสในบางสถานการณ์: ฉันจะทำเช่นนี้y = x.subscribe((x)=>data = x); แล้วผู้ใช้เปลี่ยนในอินพุตและx.subscribe((x)=>cachlist[n] = x); y.unsubscribe()เฮ้คุณใช้ทรัพยากรเซิร์ฟเวอร์ของเราฉันได้รับรางวัล t' โยนคุณออกไป ..... และในสถานการณ์อื่น ๆ : เพียงแค่โทรy.stop()โยนทุกอย่างออกไป
deadManN

16

การยกเลิกการเป็นสมาชิกจะต้องถ้าคุณต้องการพฤติกรรมที่กำหนดไว้ล่วงหน้าในทุกเครือข่ายความเร็ว

ลองนึกภาพว่าองค์ประกอบ A แสดงผลในแท็บ - คุณคลิกปุ่มเพื่อส่งคำขอ 'GET' ใช้เวลา 200 ms สำหรับการตอบกลับ ดังนั้นคุณจะปลอดภัยที่จะปิดแท็บเมื่อใดก็ตามที่รู้ว่าเครื่องจะเร็วกว่าคุณ & การตอบสนอง http จะถูกประมวลผลและเสร็จสมบูรณ์ก่อนที่แท็บจะปิดและส่วนประกอบ A ถูกทำลาย

วิธีการเกี่ยวกับเครือข่ายที่ช้ามาก? คุณคลิกปุ่มคำขอ 'GET' จะใช้เวลา 10 วินาทีในการรับการตอบกลับ แต่ 5 วินาทีในการรอให้คุณตัดสินใจปิดแท็บ นั่นจะทำลายองค์ประกอบ A ที่จะเก็บขยะในเวลาต่อมา เดี๋ยวก่อน เราไม่ได้ยกเลิกการสมัคร - ตอนนี้ 5 วินาทีต่อมาคำตอบจะกลับมาและตรรกะในองค์ประกอบที่ถูกทำลายจะถูกดำเนินการ การดำเนินการดังกล่าวได้รับการพิจารณาout-of-contextและอาจส่งผลให้หลายสิ่งรวมถึงประสิทธิภาพที่ต่ำมาก

ดังนั้นวิธีปฏิบัติที่ดีที่สุดคือการใช้takeUntil()และยกเลิกการโทรจาก http เมื่อส่วนประกอบถูกทำลาย

import { Component, OnInit, OnDestroy } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

interface User {
  id: string;
  name: string;
  age: number;
}

@Component({
  selector: 'app-foobar',
  templateUrl: './foobar.component.html',
  styleUrls: ['./foobar.component.scss'],
})
export class FoobarComponent implements OnInit, OnDestroy {
  private user: User = null;
  private destroy$ = new Subject();

  constructor(private http: HttpClient) {}

  ngOnInit() {
    this.http
      .get<User>('api/user/id')
      .pipe(takeUntil(this.destroy$))
      .subscribe(user => {
        this.user = user;
      });
  }

  ngOnDestroy(): void {
    this.destroy$.next();  // trigger the unsubscribe
    this.destroy$.complete(); // finalize & clean up the subject stream
  }
}

ใช้BehaviorSubject()แทนและโทรcomplete()เข้าไปได้ngOnDestroy()ไหม
Saksham

คุณยังคงต้องยกเลิกการสมัคร ... ทำไมจะBehaviourSubjectแตกต่างกัน?
Ben Taliadoros

ไม่จำเป็นต้องยกเลิกการสมัครจาก HttpClient นักสังเกตการณ์เนื่องจากเป็นสิ่งที่สามารถสังเกตได้แน่นอนเช่นพวกเขาเสร็จสมบูรณ์หลังจากที่ปล่อยค่า
Yatharth Varshney

คุณควรยกเลิกการสมัครต่อไปสมมติว่ามีตัวดักจับข้อผิดพลาดในการปิ้งขนมปัง แต่คุณออกจากหน้าที่เรียกข้อผิดพลาดไปแล้ว .. คุณจะเห็นข้อความแสดงข้อผิดพลาดในอีกหน้าหนึ่ง .... ลองพิจารณาหน้าตรวจสุขภาพที่ โทร microservices ทั้งหมด ... และอื่น ๆ
Washington Guedes

12

นอกจากนี้ยังมีโมดูล HttpClient ใหม่ยังคงทำงานเหมือนเดิม แพคเกจ / ทั่วไป / http / src / jsonp.ts


โค้ดด้านบนดูเหมือนว่ามาจากการทดสอบหน่วยซึ่งหมายความว่าด้วย HttpClient คุณจำเป็นต้องโทรหา complete () ด้วยตัวคุณเอง ( github.com/angular/angular/blob/ … )
CleverPatrick

ใช่คุณพูดถูก แต่ถ้าคุณตรวจสอบ ( github.com/angular/angular/blob/ ...... ) คุณจะเห็นเหมือนเดิม เกี่ยวกับคำถามหลักหากจำเป็นต้องยกเลิกการสมัครอย่างชัดเจน? ส่วนใหญ่ไม่มีกรณีเนื่องจากจะได้รับการจัดการโดยตัวเองเชิงมุม อาจเป็นกรณีที่เกิดการตอบสนองที่ยาวนานและคุณได้ย้ายไปยังเส้นทางอื่นหรืออาจทำลายส่วนประกอบในกรณีนี้คุณมีความเป็นไปได้ที่จะพยายามเข้าถึงบางสิ่งที่ไม่มีข้อยกเว้นอีกต่อไป
Ricardo Martínez

8

คุณไม่ควรยกเลิกการสมัครรับข้อมูลที่สามารถสังเกตเห็นได้โดยอัตโนมัติ (เช่น Http, การโทร) แต่ก็จำเป็นต้องยกเลิกการสมัครจาก observables Observable.timer()ไม่มีที่สิ้นสุดเช่น


6

หลังจากผ่านไปสักพักการอ่านเอกสารและซอร์สโค้ดของ HttpClient

HttpClient: https://github.com/angular/angular/blob/master/packages/common/http/src/client.ts

HttpXhrBackend : https://github.com/angular/angular/blob/master/packages/common/http/src/xhr.ts

HttpClientModule: https://indepth.dev/exploring-the-httpclientmodule-in-angular/

มหาวิทยาลัยเชิงมุม: https://blog.angular-university.io/angular-http/

Observables ประเภทนี้เป็นกระแสเดี่ยวค่า: ถ้าการร้องขอ HTTP สำเร็จ, observables เหล่านี้จะปล่อยเพียงหนึ่งค่าแล้วเสร็จ

และคำตอบของปัญหาทั้งหมดของ "ฉันต้อง" เพื่อยกเลิกการสมัครหรือไม่?

มันขึ้นอยู่กับ. Http โทร Memoryleaks ไม่ใช่ปัญหา ปัญหาคือตรรกะในฟังก์ชั่นการโทรกลับของคุณ

ตัวอย่างเช่น: การกำหนดเส้นทางหรือการเข้าสู่ระบบ

หากการโทรของคุณเป็นการโทรเข้าสู่ระบบคุณไม่จำเป็นต้อง "ยกเลิกการสมัคร" แต่คุณต้องตรวจสอบให้แน่ใจว่าผู้ใช้ออกจากหน้าเว็บนั้นหรือไม่คุณจัดการกับการตอบสนองอย่างถูกต้องหากไม่มีผู้ใช้


this.authorisationService
      .authorize(data.username, data.password)
      .subscribe((res: HttpResponse<object>) => {
          this.handleLoginResponse(res);
        },
        (error: HttpErrorResponse) => {
          this.messageService.error('Authentication failed');
        },
        () => {
          this.messageService.info('Login has completed');
        })

ตั้งแต่น่ารำคาญจนถึงอันตราย

ตอนนี้เพียงจินตนาการว่าเครือข่ายช้ากว่าปกติการโทรใช้เวลานานกว่า 5 วินาทีและผู้ใช้ออกจากมุมมองการเข้าสู่ระบบและไปที่ "มุมมองการสนับสนุน"

องค์ประกอบอาจไม่ทำงาน แต่เป็นการสมัครสมาชิก ในกรณีของการตอบสนองผู้ใช้จะถูกเปลี่ยนเส้นทางทันที (ขึ้นอยู่กับการใช้งาน handleResponse () ของคุณ)

มันไม่ดี

เพียงแค่จินตนาการว่าผู้ใช้ออกจากพีซีโดยเชื่อว่าเขายังไม่ได้เข้าสู่ระบบ แต่ตรรกะคุณบันทึกผู้ใช้ในตอนนี้คุณมีปัญหาด้านความปลอดภัย

คุณสามารถทำอะไรโดยไม่ยกเลิกการเป็นสมาชิก?

ทำให้คุณโทรขึ้นอยู่กับสถานะปัจจุบันของมุมมอง:

  public isActive = false;
  public ngOnInit(): void {
    this.isActive = true;
  }

  public ngOnDestroy(): void {
    this.isActive = false;
  }

ผู้ใช้.pipe(takeWhile(value => this.isActive))เพื่อให้แน่ใจว่าการตอบสนองจะได้รับการจัดการเฉพาะเมื่อมุมมองแอ็คทีฟ


this.authorisationService
      .authorize(data.username, data.password).pipe(takeWhile(value => this.isActive))
      .subscribe((res: HttpResponse<object>) => {
          this.handleLoginResponse(res);
        },
        (error: HttpErrorResponse) => {
          this.messageService.error('Authentication failed');
        },
        () => {
          this.messageService.info('Login has completed');
        })

แต่คุณจะแน่ใจได้อย่างไรว่าการสมัครสมาชิกนั้นไม่ทำให้เกิด memoryleaks?

คุณสามารถเข้าสู่ระบบได้หากมีการใช้ "teardownLogic"

teardownLogic ของการสมัครสมาชิกจะถูกเรียกเมื่อการสมัครสมาชิกว่างเปล่าหรือยกเลิกการเป็นสมาชิก


this.authorisationService
      .authorize(data.username, data.password).pipe(takeWhile(value => this.isActive))
      .subscribe((res: HttpResponse<object>) => {
          this.handleLoginResponse(res);
        },
        (error: HttpErrorResponse) => {
          this.messageService.error('Authentication failed');
        },
        () => {
          this.messageService.info('Login has completed');
    }).add(() => {
        // this is the teardown function
        // will be called in the end
      this.messageService.info('Teardown');
    });

คุณไม่จำเป็นต้องยกเลิกการสมัคร คุณควรทราบว่ามีปัญหาในตรรกะของคุณหรือไม่ที่อาจทำให้เกิดปัญหาในการสมัครสมาชิกของคุณ และดูแลพวกเขา ในกรณีส่วนใหญ่มันจะไม่เป็นปัญหา แต่โดยเฉพาะอย่างยิ่งในงานที่สำคัญเช่นการทำให้เป็นอัตโนมัติคุณควรดูแลพฤติกรรมที่ไม่คาดคิดด้วยการ "ยกเลิกการเป็นสมาชิก" หรือตรรกะอื่น ๆ เช่นการวางท่อหรือฟังก์ชันการโทรกลับตามเงื่อนไข

ทำไมไม่ยกเลิกการเป็นสมาชิกตลอดเวลา?

ลองนึกภาพคุณใส่คำขอหรือโพสต์ เซิร์ฟเวอร์จะรับข้อความด้วยวิธีใด ๆ การตอบสนองจะใช้เวลาสักครู่ ยกเลิกการสมัครจะไม่ยกเลิกการโพสต์หรือใส่ แต่เมื่อคุณยกเลิกการเป็นสมาชิกคุณจะไม่มีโอกาสจัดการกับคำตอบหรือแจ้งผู้ใช้ตัวอย่างเช่นผ่านกล่องโต้ตอบหรือขนมปังปิ้ง / ข้อความเป็นต้น

ซึ่งทำให้ผู้ใช้เชื่อว่าคำขอวาง / โพสต์ไม่ได้ทำ

ดังนั้นมันขึ้นอยู่กับ เป็นการตัดสินใจออกแบบของคุณวิธีจัดการกับปัญหาดังกล่าว


4

คุณควรอ่านบทความนี้อย่างแน่นอน มันแสดงให้เห็นว่าทำไมคุณควรเสมอยกเลิกการเป็นสมาชิกแม้จะมาจาก http

หากหลังจากสร้างคำขอ แต่ก่อนที่จะได้รับคำตอบจากส่วนหลังคุณเห็นว่าองค์ประกอบที่ไม่จำเป็นและทำลายมันการสมัครสมาชิกของคุณจะยังคงมีการอ้างอิงถึงองค์ประกอบจึงสร้างโอกาสในการก่อให้เกิดการรั่วไหลของหน่วยความจำ

ปรับปรุง

การยืนยันข้างต้นดูเหมือนจะเป็นจริง แต่อย่างไรก็ตามเมื่อคำตอบกลับมาการสมัคร HTTP ถูกทำลายอยู่ดี


1
ใช่แล้วคุณจะเห็นสีแดง 'ยกเลิก' ในแท็บเครือข่ายของเบราว์เซอร์ของคุณเพื่อให้แน่ใจว่ามันใช้งานได้
Simon_Weaver

-2

RxJS สามารถสังเกตได้มีความเกี่ยวข้องโดยทั่วไปและทำงานตามที่คุณสมัคร เมื่อเราสร้างสิ่งที่สังเกตได้และการเคลื่อนไหวที่เราทำเสร็จแล้วสิ่งที่สังเกตได้จะถูกปิดโดยอัตโนมัติและยกเลิกการสมัคร

พวกเขาทำงานในแบบเดียวกันกับผู้ดู แต่มีลำดับที่แตกต่างกันมาก วิธีปฏิบัติที่ดีกว่าในการยกเลิกการเป็นสมาชิกเมื่อองค์ประกอบได้รับการทำลายเราสามารถทำเช่นนั้นได้ในภายหลัง นี้. $ manageSubscription.unsubscibe ()

หากเราได้สร้างสิ่งที่สังเกตได้เช่นด้านล่างนี้กล่าวถึงไวยากรณ์เช่น

** ส่งคืน Observable ใหม่ ((ผู้สังเกตการณ์) => {** // มันทำให้สามารถสังเกตได้ในสภาวะเย็น ** observer.complete () **}) **

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.