2011-07-21 9 views
13

私が約10秒ごとにサーバーから取得する必要のあるデータがあるとします。私は、AJAXを介してデータを取得する機能を持っているし、再度この関数を呼び出すためのsetTimeoutを呼び出します。再帰的な 'setTimeout'関数呼び出しは、最終的にJSエンジンを終了させますか?

function GetData(){ 
    $.ajax({ 
     url: "data.json", 
     dataType: "json", 
     success: function(data){ 
     // do somthing with the data 

     setTimeout(GetData, 10000); 
     }, 
     error: function(){ 
     setTimeout(GetData, 10000); 
     } 
    }); 
} 

誰かが終日オープンWebページを離れた場合、それは再帰関数呼び出しの何千ものを得ることができます。

ネットワーク遅延を考慮していないため、setIntervalは使用しません。ネットワークがビジーで、要求を処理するのに15秒かかる場合は、AJAXタイムアウトを取得する前に再質問する必要はありません。

定期的に呼び出す必要がある機能を処理する最善の方法は何ですか?

+0

その後、GetDataを呼び出すと、互いに完全に独立した状態になります。 GetDataの実行が完了すると、コンテキストが破棄され、タイマーの期限が切れたときに新しいコンテキストが作成されます。 –

+0

これはおそらく、クライアント側のJavaScriptの前にサーバーの問題を引き起こすでしょう。他の人が触れたように、setTimeoutは関数がスタックに戻り、スタックから削除されるため、コールスタックの問題はありません。アルゴリズム的に再帰しますが、実際には再帰しません。 – aepheus

+0

この質問は私が研究しているものです。ここに持ってくれてありがとう。 – shaosh

答えて

21

GetDataへの呼び出しが遅れ、その間にJavaScriptコンテキストが破棄されるため、実際の再帰はありません。 JSエンジンをクラッシュさせることはありません。あなたのコードのサンプルについて

が、これはJSエンジンレベルで何が起こるか基本的には次のとおりです。

  1. 初期JSエンジン
  2. は、GetDataの関数コンテキストを作成
  3. "setTimeoutを"
  4. 含む函文を実行"setTimeOut" JSエンジンに10秒後に関数を呼び出すよう指示する
  5. GetData関数のコンテキストを破棄する
  6. この時点では、メモリ使用量に関しては、ステップ1に戻ります。唯一の違いは、JSエンジンが関数への参照を格納し、いつ呼び出すか(このデータを "futureCall"と呼ぶ)です。
  7. 10秒後、手順2から繰り返します。「futureCall」は破棄されます。
+0

この実装は依存していますか?これはJavaScriptの仕様ですか? – Robert

+0

「setTimeoutが呼び出されたコンテキストを決して破壊しない」という仕様に注目しています。これは再帰ではないので、実装が失敗したり、ひどくコード化されたものであったりする理由はありません。 –

+0

私はまだこの周りに私の頭をラッピングしている...だから私は、JS内のすべてがイベントハンドラとして実行されていると仮定すると、setTimeoutは別のイベントを処理するトリガだけです。それは独自のスタック/スレッド/プロセス/メモリ/すべてを取得します。 – Robert