私は角型アプリケーションのメニューを持っており、このメニューはWebアプリケーションの選択されたクライアントを制御します。角度およびrxJS。ストリームは決して完了しません
それがあるとして:
- 私のメニューは、サービスを経由して、選択したクライアントを共有するコンポーネントです。
- 選択したクライアントはObservableとして共有されます。
- 観測可能なものは決して完了しません。メニューがクリックされたときに新しい選択されたクライアントを送出するだけです。
- これは再生の対象です。新しい各サブスクライバは、最後に発行されたクライアントを取得します。
それは良いデザインのようでしたが、私はクライアントに基づいて新しい観察可能なものを作成するときに(観察可能なものを完成させることはありません)いくつかの問題に遭遇しました。 AFAIKこれは、最初の観測が完了せず、このプロパティが伝播するためです。
//Command
export interface Command {
productName: string;
qty: number;
}
//The service
@Injectable()
export class ClientService {
private _client: ReplaySubject<Client> = new ReplaySubject(1);
setClient(client: Client) { // The menu component calls setClient on a user click
this._client.next(client);
}
getClient(): Observable<Client> { // getClient is heavilly called in child component to observe client selection events.
return this._client.asObservable();
}
}
getCommands(): Observable<Command> { //Used in a template with async pipe
//In a child component
const commandsObs = this.clientService.getClient()
//.take(1) //I am forced to use take(1) to get getCommands() observer to complete
.flatMap(c => {
return Observable.merge(getCommandsPromise1(c), getCommandsPromise2(c));
})
.reduce((acc, next) => Object.assign({}, acc, next))
.map(next => {
return finishMakingCommand(next));
})
.catch(err => /* Some error management code*/)
}
getCommandsPromise1(client: Client): Promise<any> {
//REST call returning a promise
return Promise.resolve({ 'command1': { 'productName': 'toy', qty: 1 } });
}
getCommandsPromise2(client: Client): Promise<any> {
//REST call returning a promise
return Promise.resolve({ 'command2': { 'productName': 'another toy', qty: 1 } });
}
finishMakingCommand(commands: any): Command[] {
// Flattens 'command1' and 'command2' to a list of commands
return [{'productName': 'toy', qty: 1}, {'productName': 'another toy', qty: 2}];
}
私はより多くの経験を積んだ開発者が終わることのない、観察が良いデザインだと思うし、観測を終了することはありません回避するために、選択肢が何であるかどうかを知りたいのです。
あなたがpiplineとして観測を考える必要があります。ソースが 'Observable.interval()'のようなもので、連続的に生成するものであれば、終わりのないストリームなので、メニューのクリックで怒らなければなりません!しかし、真剣に、あなたは常にあなたのサブスクリプションを購読解除する必要があります - ここで参照してください[Angular/RxJsいつ私は 'サブスクリプション'から購読を解除する必要がありますか(https://stackoverflow.com/questions/38008334/angular-rxjs-when-should-i-subscribe- from-subscription) –
実際に私は現在、 'クライアント'オブザーバブルのすべての子に対して非同期パイプを使用しています。私が正しいとすれば、非同期パイプは自動的に退会します。 クライアントobservableは、サービスで一度インスタンス化され、ゲッターで 'asObservable'で公開されるReplaySubjectです。 –
あなたはまったく正しいです、私の友人。 –