2017-01-03 9 views
3

私はAngular 2環境でタイマーを管理しようとしています。そして、clearTimeoutは約半分の時間しか正しく動作していないようです。私はTypeScriptで書いています。clearTimeoutが散発的に失敗する

私は、独自のサービスでタイマーを保つ:

export class TimeoutService { 
    constructor(
     private router: Router, 
     private httpService: HttpService 
    ) {} 

    //Properties 
    private timer; 

    //Methods 
    public clearTimer() { 
     clearTimeout(this.timer); 
    } 

    private logOut() { 
     return this.httpService.Post('api/session/logout', ''); 
    } 

    private redirectToTimeoutPage() { 
     this.router.navigate(['/timeout']); 
    } 

    public refreshTimer() { 
     console.log('refreshing timer'); 

     if (this.timer) { 
      this.clearTimer(); 
      this.setTimer(); 
     } 
    } 

    public startTimer() { 
     this.setTimer(); 
    } 

    private setTimer() { 
     this.timer = setTimeout(() => { 
      this.logOut() 
       .then(() => { 
        this.clearTimer(); 
        this.redirectToTimeoutPage(); 
       }); 
     }, 30000); 
    } 
} 

私はそれがそうでなければ、私はそれがあることを期待したときに呼び出され、いないされているrefreshTimer方法ではconsole.logから知っています。しかし、ほとんどの場合、以前のタイマーはclearTimeoutコールによって取り消されず、新しいタイマーに置き換えても30秒後に起動します。

私はこのことに関する他の質問をしてきましたが、私が見る限り、私の状況には該当しません。

私が解読できない1つの手がかりは、refreshTimer内のthis.setTimer()への呼び出しを取り除くと、clearTimeout呼び出しが正常に機能しているようです。言い換えると、新しいタイマーを作成すると、何とか古いタイマーが生き残るようになります。私はここで何が欠けていますか?

ありがとうございました!

+0

TimeoutServiceクラスの実際の使用状況を示すコードをいくつか含めることができますか? – Zack

+0

ベストプラクティスとして、常に変数を初期化することをお勧めします。タイマーの場合(後でその存在をチェックしているので)、ヌルに初期化します(つまり、 'private timer = null;') –

答えて

5

refreshTimerで。

startTimerでは、this.clearTimer()には電話をかけません。したがって、呼び出しコードがを呼び出して何もせずにstartTimerを複数回呼び出す場合は、複数のタイムアウトを開始することになりますが、最後のものだけがクラスによって記憶され、this.clearTimerが再び呼び出されたときには、をキャンセルします。

+0

1つでそれを手に入れました!どうもありがとう。 –

1

私はclearTimerへの呼び出しをsetTimer関数に移動し、それが役立つかどうかを確認します。

2

あなたclearTimeout機能では、あなたはタイマーをクリアするだけでなく、あなたもあなたのtimer変数をリセットしたい:

public clearTimer() { 
    clearTimeout(this.timer); 
    this.timer = null; // <-- You also want your variable to become null here. 
} 

その後、clearTimer()への呼び出しの後に実行される任意のコードが正しく評価されますtimerは、タイマーが存在しないことを正確に示すnullという変数です。実行中のタイマーを停止するだけでは、ラッパーでは不十分です。

また、私がコメントで述べたように、すべての変数を初期化して、どこからでも「驚き」の値が表示されないようにすることは、非常に良いベストプラクティスです。

private timer; 

する必要があります:あなたは this.setTimer()を呼び出す前 this.clearTimer()を呼び出すの世話を

private timer = null; 
+0

あなたの考えをありがとう、私はそれらをコードに統合しましたベストプラクティスとして。 –

関連する問題