2017-07-14 12 views
2

AsyncSubjectは、最後のサブジェクトオブザーバーがサブジェクトをサブスクライブしないときに観察可能になります。ここにはthe quote最後のオブザーバーがサブスクライブを解除したときにAsyncSubjectが完了しないようにする方法

完了しました。被験者は、 の登録を解除、完了、またはエラーが発生した後で再利用することはできません。ここで

デモです:

const ofObservable = Rx.Observable.of(1, 2, 3); 
const subject = new Rx.AsyncSubject(); 

ofObservable.subscribe(subject); 

subject.subscribe((v) => { 
    console.log(v); 
}); 

subject.unsubscribe((v) => { 
    console.log(v); 
}); 

// here I'll get the error "object unsubscribed" 
subject.subscribe((v) => { 
    console.log(v); 
}); 

完了することから、被写体を防ぐためにどのように?

shareオペレータあります:RxJS 5では

は、オペレータshare()はホットになり、失敗した場合に再試行、または成功に繰り返すことができ、観察 をrefCounted。 被験者が退会し、彼らはエラーが発生したしたら、再利用完了あるいは することはできませんので、share()オペレータは、結果として、観察に再購読を有効 に死んだ科目をリサイクルします。

これは私が探しているものです。しかし、shareは件名を作成し、AsyncSubjectが必要です。

+0

は、[このテスト](https://github.com/ReactiveX/rxjs/blob/5.4.2/spec/subjects/AsyncSubject-spec.ts#L125-L141)それは道あなたが行動する必要があります示唆しますそれを期待しています、そうではありませんか?何か他のことが起こっていますか? – cartant

+0

こんにちは、ありがとう、[このplunker](https://plnkr.co/edit/wFRWuiyWtsolP5CESdaA?p=preview)にチェックしてください。他に何もありません。 –

+1

これはちょっとタイプミスのようです。 'subject.subscribe'呼び出しの結果を変数に代入します(結果はサブスクリプションです)。サブジェクトではなくサブスクリプションに対して' unsubscribe'を呼び出します。その変化に伴い、私は予想していたことをしているようです。 – cartant

答えて

2

問題がダウンし、この行にある:

subject.unsubscribe((v) => { 
    console.log(v); 
}); 

Subjectimplements ISubscription。つまり、unsubscribeメソッドとclosedプロパティを持っています。多少残酷である

unsubscribe() { 
    this.isStopped = true; 
    this.closed = true; 
    this.observers = null; 
} 

を次のようにそのimplementation of unsubscribeです。基本的に、サブスクライバの登録を解除することなく、そのサブスクライバとのすべての通信を切断します。同様に、サブスクライブは、サブスクライブされる可能性のある観察可能なものからサブジェクト自体を購読解除しません。

これは、実際にはどのように使用されているのか分かりませんが、どのように使用されるのかは不明です。 this testの説明: - 退会処分と命名された

it('should disallow new subscriber once subject has been disposed',() => { 

は、それがRxJS 4から二日酔いのいくつかの並べ替えであるかもしれないことを示唆しています。

その理由は何でも、私は決してそれを呼び出すことをお勧めします。一例として、このスニペットを見て:それは、被験者から観察合成に加入し、次いで観察ソースの対象をサブスクライブし、

const source = Rx.Observable 
 
    .interval(200) 
 
    .take(5) 
 
    .do(value => console.log(`source: ${value}`)); 
 

 
const subject = new Rx.Subject(); 
 
source.subscribe(subject); 
 

 
const subscription = subject 
 
    .switchMap(() => Rx.Observable 
 
    .interval(200) 
 
    .take(5) 
 
    .delay(500)) 
 
    .subscribe(value => console.log(`subscription: ${value}`));
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>

unsubscribeた場合は、問題のカップルが明らかになる、被写体に呼び出されます。

  • ソースへの被験者のサブスクリプションが解除ではなく、ソースは、被験者のnextメソッドを呼び出そうとしたときにエラーが行われます。
  • サブジェクトから構成されたオブザーバブルのサブスクリプションはサブスクライブされていないため、switchMap内で観測可能なintervalunsubscribeコールが発信された後でも発信し続けます。

それを試してみてください:この

const source = Rx.Observable 
 
    .interval(200) 
 
    .take(5) 
 
    .do(value => console.log(`source: ${value}`)); 
 

 
const subject = new Rx.Subject(); 
 
source.subscribe(subject); 
 

 
const subscription = subject 
 
    .switchMap(() => Rx.Observable 
 
    .interval(200) 
 
    .take(5) 
 
    .delay(500)) 
 
    .subscribe(value => console.log(`subscription: ${value}`)); 
 

 
setTimeout(() => { 
 
    console.log("subject.unsubscribe()"); 
 
    subject.unsubscribe(); 
 
}, 700);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>

どれもそうSubjectunsubscribeを呼び出して、望ましい行動のように見えない避けるべき何かがあります。

代わりに、あなたのスニペット内のコードはsubscribe呼び出しによって返さSubscription使用して解除する必要があります。この答えを書くに続き

const subscription = subject.subscribe((v) => { 
    console.log(v); 
}); 
subscription.unsubscribe(); 

を、私は合うBen Leshからfollowing commentを、見つけました被験者の処分に関連していると私の理論では考えています。

0123のときに被験者に大声で怒ってもらいたい場合はそれが有用になった後でそれにを追加すると、unsubscribeをサブジェクトインスタンス自体に直接呼び出すことができます。

+0

あなたの深い分析のために、ありがとう! –

+0

あなたはオブザーバブルについて何か書いていますか?ブログかもしれない? –

+0

最近、メディアに書き始めることを決めました。Stack Overflowプロファイルにリンクがあります。 – cartant

関連する問題