2017-03-09 60 views
1

我有一個訂閱,我想用一箇中間件代碼來表示事件。所以我有一件事想要訂閱一個可觀察的事物,而另一件事情是不可觀察的。使用subscription.next()是否爲反模式?

我想過使用科目爲這一點 - 這就是表裏如一成爲:

const repeater = new Rx.Subject(); 

function subscribe(observer) { 
    return repeater.subscribe(observer); 
} 

// in some other function, call repeater.next(val) 

但後來,我開始尋找什麼定期訂閱()調用返回。我可以這樣做:

let sub = null; 
function subscribe(observer) { 
    return Rx.Observable.create((o) => sub = o); 
} 
// elsewhere sub.next(val) 

但是呢?

let unsub = null; 
function subscribe(observer) { 
    unsub = Rx.Observable.create(() => false).subscribe(observer) 
} 
// elsewhere unsub.next(val) 

所有這些東西都會向用戶發出val的信號。我在這裏不明白的奇怪的事情是有next()可用的訂閱返回 - 我認爲next()只生活在Observable上下文中的觀察者。

無論什麼時候我都需要對取消訂閱的東西保持控制 - 當中間件被拆除時,我需要發出信號流完成並釋放一些資源。令我感到意外的是,未接電話下一個功能正常。

這告訴我有一些RxJS,就觀察者和觀察者和主題等而言,我只是不明白。一般來說,我知道如何將事件源和其他類似事物連接到可觀察的流中。這實際上只是在無聊函數調用中構建可觀察流的上下文中 - 無論何時該函數被外部​​庫調用,該流都會發出更新後的可觀察事件。

回答

3

訂閱者擴展了Subscription和Observer,添加了狀態。它揭露了一種改變狀態的方法(即unsubscribe()),並且它也暴露了觀察者的方法/error()/方法 ,但是這些方法現在既能夠承認狀態又能改變狀態。

所以,如果我給你一個裸露的觀察者,你可以調用next()/error()/complete()它 以任何順序,多次,只要你想,即使它是 可怕的爲你以後叫我next()你叫我complete()

在另一方面,如果我給你一個 用戶包裹起來的觀察,現在有狀態的,如果你嘗試調用next()上 你叫complete()用戶之後,我將無法看到它。 如果您撥打unsubscribe(),我會分開。

當你打電話訂購,如

subscriber = Rx.Observable.create(fn).subscribe(observer); 

你又回到同一觀察者,而只是觀察者,一個包裹裏面用戶 。這就是爲什麼你看到next()/error()/complete()方法。但是,這些方法通常是供內部使用,如果你用它來養活一個觀察者,它不會做你所期望的:

let observerA = { 
    next: (x) => console.log('A: value: ' + x), 
    error: (x) => console.log('A: error: ' + x), 
    complete:() => console.log('A: completed') 
} 
let observerB = { 
    next: (x) => console.log('B: value: ' + x), 
    error: (x) => console.log('B: error: ' + x), 
    complete:() => console.log('B: completed') 
} 

let observable = Rx.Observable.create(() => false); 
let subscriberA = observable.subscribe(observerA); 
let subscriberB = observable.map(x => 10*x).subscribe(observerB); 
subscriberA.next(1); // only feeds observerA 
// => "A: value: 1" 
subscriberB.next(2); // only feeds observerB 
// => "B: value: 2" // What? 

賠率是,你的使用情況,您會

  1. 想用的問題,因爲它可以讓你next()/error()/complete()接口,讓你喂操作鏈的最前端,
  2. 想用的問題,因爲它可以讓你喂相同的值到多個觀察員,
  3. 忘記您剛纔瞭解的訂閱用戶,因爲您不打算使用訂閱者界面。相反,請將subscribe()返回的對象視爲僅限訂閱,並且僅對其使用unsubscribe()方法。

所以:

let subject = new Rx.Subject(); 
let subscriptionA = subject.subscribe(observerA); 
let subscriptionB = subject.map(x=>10*x).subscribe(observerB); 
subject.next(3); 
// => A: value: 3 
// => B: value: 30 
subscriptionA.unsubscribe() 
subject.next(4); 
// => B: value: 40 
subscriptionB.unsubscribe() 
subject.next(5); 
// (no output) 

另見When to use asObservable() in rxjs?

+1

啊哈!那'subscriberB.next(2); // =>「B:value:2」'部分確實固化了它。這現在很有意義。真棒回答。 – pfooti

相關問題