2017-01-27 16 views
1

私はAngular 2とRxJSを使用しています。シンプルなobservablesシステムをセットアップするのに苦労しています。rxJS observableがsubscribeに達していない

私が理解する限り、演算子doは副作用に使用され、susbcribe()関数でobservableから返された結果を処理するコードを配置します。

私のコンポーネントは、システムにシステムの初期化を依頼します。 サービスはサーバーへの2回のhttp呼び出しを行い、コンポーネントを1つのストリームにまとめて加入し、すべての準備が整ったことを確認します。 サービス内の2つのhttp呼び出しのうちの1つが、サーバーから一定数の結果を取得しており、要求に応じてコンポーネントに配信されます。そのため、サービスはより多くのデータを必要とすると見て、サーバーに別の呼び出しを行います。

新しいhttpコールを作成する前に最初に元のhttpコールを登録解除する必要があると思うので、これは機能しませんでした(それは本当ですか?)。

これは私が持っているものです... getQuestionsメソッドで購読していないので動作しません。

コンポーネントで

ngOnInit() { 
    // show spinner 

    this.gamesService 
     .initializeGame() 
     .subscribe(data => { 
     console.log('Game initialized'); 
     // remove spinner 
     }); 
    } 
サービスで

initializeGame(opponent_id: string): Observable<any> { 
    return Observable 
     .forkJoin([this.getQuestions(), this.newGame()]); 
    } 

    getQuestions(): Observable<any> { 
    // composes postData with POST parameters 

    this.questionsObservable = this.authHttp 
     .post(this.settings.authApiUrl, postData) 
     .map((response: Response) => response.json()); 

    this.questionsObservable 
     .subscribe(data => { 
     // save data in the service, which will be consumed 
     }) 
     .unsubscribe(); // do I need to unsubscribe? 

    return this.questionsObservable; 
    } 

    getQuestion(category: string): any { 
    // consume question by Component 
    if (no_more_questions_in_service) this.getQuestions(); 
    return question; 
    } 

ので、これが今取り組んでいます。 なぜ購読方法に達していないのですか?

これを達成するより良い方法はありますか? ありがとう

+2

'authHttp'サービスがアイテムを発行する前に、あなたは' .unsubscribe() 'を退会します。 – martin

答えて

1

わかりました(また、感謝@マーティン)私は時間の前に退会していました。

誰かが使いたいと思ったら、私が望むものを手に入れました。

サービスは、次のようになりました:

initializeGame(opponent_id: string): Observable<any> { 
    return Observable 
     .forkJoin([this.getQuestions(), this.newGame()]); 
    } 

    getQuestions(): Observable<any> { 
    // postData 

    return this.authHttp 
     .post(this.settings.authApiUrl, postData) 
     .map((response: Response) => response.json()) 
     .do(data => save_data); 
    } 

    private getQuestionsByCategory(category: string) { 
    // postData 

    this.authHttp 
     .post(this.settings.authApiUrl, postData) 
     .map((response: Response) => response.json()) 
     .subscribe(data => save_data 
    } 

    getQuestion(category: string): any { 
    // consume question by Component 
    if (no_more_questions_in_service) 
     this.getQuestionsByCategory(category); 
    } 
    return question; 
    } 

だから私は今、2種類の方法があります。私は購読を解除する必要はありません(私は思う)、今はうまくいっているようです。

+0

一般的に、サービス自体は、ラップするオブザーバブルには登録しないでください。代わりに、サービスの**消費者**はすべきです。あなたの場合、コンポーネントはサービスではなくサブスクライブする必要があります。具体的には、なぜgetQuestionsByCategory()に 'subscribe()'があるのか​​わかりません。購読者が受け取るデータで何もしていないようです。 – AngularChef

+0

ありがとう@AngularFrance、getQuestionsByCategory()では、私がやっているのは、サーバーからローカルに取得したデータを私のサービスに格納することです。この場合、subscribe()の代わりにdo()を使うべきですか? 私は、コンポーネントがサブスクリプションである必要があることを理解していますが、この場合コンポーネントは一度にすべてのデータを使用するわけではなく、一度に1つのアイテムしか必要とせず、 – David

+0

サービスでデータをキャッシュしたいのですか?次の2つのシナリオがあります。1)最初にコンポーネント**を購読するときに、そのデータを(サービスのプライベートプロパティとして)キャッシュするか、その後の呼び出しで、観測データを再実行する前にデータがすでに存在するかどうかをチェックします。 2)または、コンポーネントがサブスクライブする前にも、キャッシュを積極的に取り込みたい。その場合、あなたはどこかで購読する必要があることに同意しますが、それでも私はそのサービスの中に置かないでしょう。 – AngularChef

関連する問題