2017-08-10 12 views
1

私は一度だけ電話をかけたいと思います。呼び出しがすでに完了している場合は、ローカル変数を返す必要があります。角2サービス:ローカル変数を返すか約束をしてください

サービス:

public currentUser: User; 

getUser() { 
    if (this.currentUser) { 
     return this.currentUser; 
    } 
    else { 
     return this.http.get('/api/user/') 
      .toPromise() 
      .then(response => { 
       this.currentUser = response.json() as User; 
       return this.currentUser; 
      }); 
    } 
} 

ユーザがnullの場合、呼び出しが行われるが、呼び出しが非同期であるため、コンポーネントで取得しません。それをどうすれば実現できますか?それは最初の時間を働いている

getUserFromService() { 
    let serviceReturn = this.userService.getUser(); 

    if (serviceReturn instanceof User) { 
     this.user = serviceReturn; 
    } 
    else { 
     let promise = serviceReturn as Promise<User>; 
     promise.then(
      response => { 
       this.user = response; 
      } 
     ); 
    } 
} 

が、二回目は、それがユーザとしてserviceReturnを認識し、エラーをスローelseを、行っておりません。

私はコンポーネントでこれを試してみました。そして、それは良い方法ではないと思います。より良い方法でなければなりません。

+0

'this.http.get'から約束を取り戻していますか? –

+0

はい、質問の行を忘れました。編集しました:) – Robouste

答えて

2

しかし、Promise<User>Userの2種類の返品タイプがあります。それから、あなたのサービスの消費者は、常に彼らが受け取っているものを確認する必要があります。ベストは常にPromiseを返すために、次のようになります。

private currentUser: Promise<User>; 

getUser() { 
    if (!this.currentUser) { 
     this.currentUser = this.http 
      .get('/api/user/') 
      .map(r => r.json()) 
      .toPromise(); 
    } 
    return this.currentUser; 
} 

今、すべての消費者が行う必要があります:あなたはそれが常にれるメソッドの前でasyncキーワードを追加した場合だけ心に留めておく

async doSomething(): Promise<any> { 
    let user: User = await this.userService.getUser(); 
} 

Promiseを返します。このPromiseには、このメソッド内に返すものが含まれます。あなたはこれを使用したくない場合は、常にこのように取り掛かることができますが、あなたのコードの可読性が下がる:

doSomething(): any { 
    this.userService.getUser().then((user: User) => { 

    }); 
} 
+0

これはうまくいくはずですが、私は 'Promise.resolve()'で他の答えを好むです。 – Robouste

+0

@Robousteもう一つの答えには小さなデザインの欠陥がありますメソッドを2回呼び出すと、最初に返されていないので、同じ要求を2度サーバーに実行します。私の答えは、このようなひどい結果を被ることはありません – PierreDuc

+0

私は、2つの異なるコンポーネントが同じページでサービスを呼び出しているときにユーザーが2回読み込まれていることに気付きました。私はこの解決策を試してみましょう。 – Robouste

0

async/awaitもので周りのビットを演奏した後、私はそれを使用してもOKかもしれないと思いますasync/awaitサービスの内部、代わりにPromise<User>の実際のUserとしてあるCurrentUserがあります

private currentUser: User; 

async getUser() { 
    if (!this.currentUser) { 
     this.currentUser = await this.http 
      .get('/api/user/') 
      .map(r => r.json()); 
    } 
    return this.currentUser; 
} 

今常にPromise<User> を返すgetUser()方法私は、コードはこのよう少し良く読めると思います。欠点は明らかにの中にのサービスがある場合は、currentUserの代わりにgetUser()を直接使用してください。

関連する問題