RxJS: ฉันจะ“ อัปเดตด้วยตนเอง” แบบสังเกตได้อย่างไร


139

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

โดยทั่วไปฉันต้องการทำสิ่งนี้:

// create a dummy observable, which I would update manually
var eventObservable = rx.Observable.create(function(observer){});
var observer = eventObservable.subscribe(
   function(x){
     console.log('next: ' + x);
   }
...
var my_function = function(){
  eventObservable.push('foo'); 
  //'push' adds an event to the datastream, the observer gets it and prints 
  // next: foo
}

pushแต่ผมยังไม่ได้รับสามารถที่จะหาวิธีการเช่น ฉันใช้ตัวจัดการการคลิกและฉันรู้ว่าพวกเขามีObservable.fromEventสิ่งนั้น แต่ฉันพยายามใช้กับ React และฉันอยากจะอัปเดตสตรีมในการโทรกลับแทนที่จะใช้ที่แตกต่างกันโดยสิ้นเชิง ระบบการจัดการเหตุการณ์ โดยพื้นฐานแล้วฉันต้องการสิ่งนี้:

$( "#target" ).click(function(e) {
  eventObservable.push(e.target.text()); 
});

ฉันได้ใช้ที่ใกล้เคียงที่สุดobserver.onNext('foo')แต่ดูเหมือนจะไม่ได้ผลจริงและถูกเรียกใช้จากผู้สังเกตการณ์ซึ่งดูเหมือนจะไม่ถูกต้อง ผู้สังเกตการณ์ควรเป็นสิ่งที่ตอบสนองต่อกระแสข้อมูลไม่ใช่การเปลี่ยนแปลงใช่ไหม

ฉันไม่เข้าใจความสัมพันธ์ของผู้สังเกตการณ์ / ที่สังเกตได้หรือไม่?


มีลักษณะที่นี้เพื่อชี้แจงความคิดของคุณ (แนะนำการเขียนโปรแกรมปฏิกิริยาที่คุณได้รับหายไป): gist.github.com/staltz/868e7e9bc2a7b8c1f754 ที่นี่ก็มีทรัพยากรมากมายที่คุณสามารถปรับปรุงความเข้าใจของคุณ: github.com/Reactive-Extensions/RxJS#resources
user3743222

ฉันเช็คเอาท์ก่อนดูเหมือนว่าทรัพยากรที่แข็งแกร่ง รายการที่สองเป็นรายการที่ยอดเยี่ยมฉันพบaaronstacy.com/writings/reactive-programming-and-mvcซึ่งช่วยให้ฉันค้นพบ Rx.Subject ซึ่งแก้ปัญหาของฉันได้ ขอบคุณมาก! เมื่อฉันเขียนแอพขึ้นมาอีกเล็กน้อยฉันจะโพสต์โซลูชันของฉันเพียงแค่ต้องการทดสอบการต่อสู้เล็กน้อย
เลียม

เฮ้ขอบคุณมากที่ถามคำถามนี้ฉันกำลังจะถามคำถามเดียวกันกับตัวอย่างโค้ดที่เหมือนกันในใจ :-)
arturh

คำตอบ:


154

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

คุณสามารถทำสิ่งนี้:

var eventStream = new Rx.Subject();

var subscription = eventStream.subscribe(
   function (x) {
        console.log('Next: ' + x);
    },
    function (err) {
        console.log('Error: ' + err);
    },
    function () {
        console.log('Completed');
    });

var my_function = function() {
  eventStream.next('foo'); 
}

คุณสามารถหาข้อมูลเพิ่มเติมเกี่ยวกับวิชาที่นี่:


1
นี่คือสิ่งที่ฉันทำลงไป! ฉันพยายามอย่างต่อเนื่องเพื่อดูว่าฉันจะหาวิธีที่ดีกว่าในการทำสิ่งที่ฉันต้องทำหรือไม่ แต่นี่เป็นวิธีแก้ปัญหาที่ทำงานได้จริง ฉันเห็นมันครั้งแรกในบทความนี้: aaronstacy.com/writings/reactive-programming-and-mvc
เลียม

34

ฉันเชื่อObservable.create()ว่าไม่ได้ใช้ผู้สังเกตการณ์เป็นโทรกลับ แต่เป็นอีซีแอล ดังนั้นหากคุณต้องการเพิ่มค่าใหม่ให้กับObservableให้ลองทำสิ่งนี้แทน:

var emitter;
var observable = Rx.Observable.create(e => emitter = e);
var observer = {
  next: function(next) {
    console.log(next);
  },
  error: function(error) {
    console.log(error);
  },
  complete: function() {
    console.log("done");
  }
}
observable.subscribe(observer);
emitter.next('foo');
emitter.next('bar');
emitter.next('baz');
emitter.complete();

//console output
//"foo"
//"bar"
//"baz"
//"done"

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


เป็นไปได้ของการเขียนทับคุณสมบัติของอีซีแอลอยู่ที่ไหนสักแห่งในคู่มือ RxJS?
โทมัส

ในกรณีนี้emitterจะมีเฉพาะnext()ค่าใหม่สำหรับผู้สังเกตการณ์ที่สมัครรับข้อมูลล่าสุดเท่านั้น วิธีที่ดีกว่าคือการรวบรวมทั้งหมดemitterในชุดและวนซ้ำผ่านพวกเขาทั้งหมดและnextคุณค่าของแต่ละรายการ
Eric Gopak
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.