สังเกตได้ในที่สุดเมื่อสมัครสมาชิก


106

ตามartcle นี้ , onCompleteและonErrorฟังก์ชั่นของการsubscribeอยู่ร่วมกันอย่างเดียว

ความหมายอย่างใดอย่างหนึ่งonErrorหรือonCompleteเหตุการณ์ต่างๆจะเริ่มขึ้นในsubscribeไฟล์.
ฉันมีบล็อกลอจิกที่จำเป็นต้องดำเนินการไม่ว่าฉันจะได้รับข้อผิดพลาดหรือฉันทำข้อมูลให้เสร็จสมบูรณ์

ฉันมองหาบางอย่างเช่นfinallyใน pythonแต่สิ่งที่ฉันพบคือfinallyสิ่งที่ต้องแนบกับสิ่งที่สังเกตได้ที่ฉันสร้างขึ้น

แต่ฉันต้องการใช้ตรรกะนั้นเฉพาะเมื่อฉันสมัครและหลังจากสตรีมสิ้นสุดลงไม่ว่าจะสำเร็จหรือมีข้อผิดพลาด

ความคิดใด ๆ ?

คำตอบ:


135

ตัวแปร "pipable" ปัจจุบันของตัวดำเนินการนี้เรียกว่าfinalize()(ตั้งแต่ RxJS 6) มีการเรียกตัวดำเนินการ "patch" ที่เก่ากว่าและตอนนี้เลิกใช้แล้วfinally()(จนถึง RxJS 5.5)

ฉันคิดว่าfinalize()ตัวดำเนินการถูกต้องจริงๆ คุณพูด:

ใช้ตรรกะนั้นเฉพาะเมื่อฉันสมัครและหลังจากสตรีมสิ้นสุดลง

ซึ่งไม่ใช่ปัญหาที่ฉันคิด คุณสามารถมีซิงเกิ้ลsourceและใช้finalize()ก่อนสมัครสมาชิกได้หากต้องการ วิธีนี้คุณไม่จำเป็นต้องใช้เสมอไปfinalize():

let source = new Observable(observer => {
  observer.next(1);
  observer.error('error message');
  observer.next(3);
  observer.complete();
}).pipe(
  publish(),
);

source.pipe(
  finalize(() => console.log('Finally callback')),
).subscribe(
  value => console.log('#1 Next:', value),
  error => console.log('#1 Error:', error),
  () => console.log('#1 Complete')
);

source.subscribe(
  value => console.log('#2 Next:', value),
  error => console.log('#2 Error:', error),
  () => console.log('#2 Complete')
);

source.connect();

สิ่งนี้จะพิมพ์ไปยังคอนโซล:

#1 Next: 1
#2 Next: 1
#1 Error: error message
Finally callback
#2 Error: error message

ม.ค. 2019: อัปเดตสำหรับ RxJS 6


1
น่าสนใจว่ามันเป็นรูปแบบที่ตรงกันข้ามกับคำสัญญาโดยfinally()วิธีนี้จะถูกต่อท้ายก่อนและการสมัครสมาชิกจำเป็นต้องบังคับให้ผ่าน / ไม่ผ่าน
BradGreens

7
ใช่ว่าแย่เกินไป ใครจะคิดว่าfinallyบล็อกจะมาอยู่ในรหัสของคุณ
d512

ฉันชอบระบบสัญญาของ Angular JS ... ดังที่ d512 บอกว่าฉันคาดว่า "ในที่สุด" จะเป็นครั้งสุดท้าย ... ไม่ชอบสิ่งนี้เลย ...
Sampgun

10
สำหรับ RXJS 5.5 "ในที่สุด" ไม่ใช่วิธีสังเกตอีกต่อไป ใช้ตัวดำเนินการ "finalize" แทน: source.pipe (finalize (() => console.log ('โทรกลับในที่สุด'))) สมัครสมาชิก (... ); github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md
Stevethemacguy

ปัญหาในการสรุปคือรอการเรียก "complete ()" จะเกิดอะไรขึ้นถ้าคุณต้องการสุดท้ายในการปล่อยแต่ละครั้ง (หากการปล่อยที่สังเกตได้เป็นความสำเร็จให้ทำaหากมีข้อผิดพลาดให้ทำbแทน .. ในทั้งสองกรณีทำc )?
roberto tomás

68

สิ่งเดียวที่ใช้ได้ผลสำหรับฉันคือสิ่งนี้

fetchData()
  .subscribe(
    (data) => {
       //Called when success
     },
    (error) => {
       //Called when error
    }
  ).add(() => {
       //Called when operation is complete (both success and error)
  });

26

ตอนนี้ฉันใช้ RxJS 5.5.7 ในแอปพลิเคชั่นเชิงมุมและการใช้finalizeตัวดำเนินการมีพฤติกรรมแปลก ๆ สำหรับกรณีการใช้งานของฉันเนื่องจากถูกยิงก่อนที่จะสำเร็จหรือเรียกกลับผิดพลาด

ตัวอย่างง่ายๆ:

// Simulate an AJAX callback...
of(null)
  .pipe(
    delay(2000),
    finalize(() => {
      // Do some work after complete...
      console.log('Finalize method executed before "Data available" (or error thrown)');
    })
  )
  .subscribe(
      response => {
        console.log('Data available.');
      },
      err => {
        console.error(err);
      }
  );

ฉันต้องใช้addmedhod ในการสมัครสมาชิกเพื่อบรรลุสิ่งที่ฉันต้องการ โดยทั่วไปแล้วการfinallyโทรกลับหลังจากการเรียกกลับสำเร็จหรือข้อผิดพลาดเสร็จสิ้น เช่นเดียวกับtry..catch..finallyบล็อกหรือPromise.finallyวิธีการ

ตัวอย่างง่ายๆ:

// Simulate an AJAX callback...
of(null)
  .pipe(
    delay(2000)
  )
  .subscribe(
      response => {
        console.log('Data available.');
      },
      err => {
        console.error(err);
      }
  );
  .add(() => {
    // Do some work after complete...
    console.log('At this point the success or error callbacks has been completed.');
  });

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