2013-06-28 5 views
7

は(私は全く同様の質問/回答を見てきたが、それらのどれも私の問題を解決しません。)動作していないはJavaScriptてclearTimeout

コード:

var timeoutHandle; 

function showLoader(show) { 
    if (show) { 
     $('.loader').html('Loading...'); 
     $('.loader').show(); 

     timeoutHandle = setTimeout(function() { 
      if ($('.loader').is(':visible')) { 
       $('.loader').html('Still loading...'); 
      } 
     }, 15000); 
    } 
    else { 
     $('.loader').hide(); 
     clearTimeout(timeoutHandle); 
    } 
} 

AJAX機能は、単に呼び出すshowLoader(true)を呼び出す前に、サーバー、その後はshowLoader(false)です。私は時々15秒前に "Loading ..."から "Still loading ..."にテキストが変わるのを見ているので、それはあたかもタイマースレッドが走っているかのようです。上記のコードに何か問題がありますか?それとも問題が...他のコードとの可能性があり

編集:私は

+0

を存在する場合、 "showLoader" を呼び出す関数とは何ですか?そのコードを見ることはできますか? –

答えて

14

あなたはそこかどうかを確認するためのチェックを追加する必要があり、サーバーからの応答の前にshowLoader(true)が再び呼び出され(そして再び)することができることを追加する必要があります新しいものを作成する前にすでにtimeoutHandleです。

これを試してみてください。それ以外の場合は、その後

if(timeoutHandle){ 
    clearTimeout(timeoutHandle); 
    timeoutHandle = null; 
} 
timeoutHandle = setTimeout(function() { 
    if ($('.loader').is(':visible')) { 
     $('.loader').html('Still loading...'); 
    } 
}, 15000); 

とはそうのように明確にした後、ヌルにそれをtimeoutHandleを設定します。

clearTimeout(timeoutHandle); 
timeoutHandle = null; 

showLoader(true)場合、これはあなたが同時タイムアウトを作成する可能性を排除します関数が複数回呼び出されます。

+7

チェックする必要はありません。 'clearTimeout'を呼ぶだけです。 – Ian

3

showLoaderは、どこからでもアクセスできるグローバルな機能であるため、複数の電話をshowLoaderに発信している可能性があります。

私はモナド実装にそれを変更することを検討します:

function create_loader(elem) { 
    var handle = null; 

    function show() { 
     elem.html('Loading...'); 
     elem.show(); 

     if (handle !== null) { 
      clearTimeout(handle); // clear the previous one 
     } 
     handle = setTimeout(function() { 
      elem.html('Still loading...'); 
     }, 15000); 
    } 

    return { 
     show: show, 
     clear: function() { 
      elem.hide(); 
      clearTimeout(handle); 
      handle = null; 
     } 
    }; 
} 

は使用方法:

var loader = create_loader($(".loader")); 
loader.clear(); 
loader.show(); 
loader.show(); // each new call to show will reset the 15s timer 
loader.show(); 
loader.show(); 
loader.clear(); 
// and you can make another one that operates independently of other one 
var another_loader = create_loader($(".anotherLoader")); 

今、あなたはそれ自身の状態について知っているloaderオブジェクトを持っています。

+0

非常に有益です、ありがとうございます。オマールの解決策は私には分かりやすいです。 – user982119

+0

Omarのソリューションは問題ありません。私は 'timeoutHandle'をグローバルスコープから削除し、ローダーのインスタンスに結びつけます。現在は 'loader'だけがグローバルスコープにあり、自分の状態を保持します。 – Halcyon

+0

タイマーIDをカプセル化するために+1します。これをさらに進めて、ロードが完了したときのコールバックを追加できます。 –

1

最初の返信前にshowloaderを複数回呼び出すことができます。これがあなたの問題です。すでに存在するハンドルを破棄することなく、既存のtimeoutHandleを新しいもので上書きしています。新しいものを作成する前に、timeoutHandleが設定されているかどうかを確認する必要があります。

0

あなたは新しい要求を開始し、その後てclearTimeout(timeoutHandle)を呼び出すことはありません、timeoutHandleは

関連する問題