2012-05-08 16 views
0

外部ファイルを変更して保存するサーブレットと通信しています。これには時間がかかるので、ある関数のアクションが別の関数のアクションを抱かないように、javascriptの関数呼び出しを順次実行する必要があります。順次関数呼び出し

これを行うには、busyflagがfalseに設定されているとき(つまり、他のfunctioncallが同時に処理されないとき)にのみ呼び出される別の関数を使用する 'sequential'関数を書いた。これは私のコードです:

var busy = false; 
function sequential(action) { 
    while(busy) 
     setTimeout(function(){sequential(action);}, 10); 
    busy = true; 
    action(); 
    setTimeout(function(){busy = false;}, 100); 
} 

function test1() {sequential(function() {alert("test1");});} 
function test2() {sequential(function() {alert("test2");});} 

そしてthisはjsFiddle上の例です。なんらかの理由で、このコードは2番目の呼び出しでループし続けます(functioncallが待機しなければならない場合)。

+0

私はあなたが[Deferredの作り方](http://api.jquery.com/category/deferred-object/)が役立つかもしれないと思います... – elclanrs

答えて

0

は、私が最初のジェームズ・モンターニュによって提案されたようなソリューションを実現しますが、いくつかのSearchさらに後に私はあなたがのonreadystatechangeにプロパティを使用することができることが判明しましたXMLHttprequestを使用してbusy-flagをtrueに設定します。

このコードは期待のように動作します:

function sequential(action) { 
if (busy) setTimeout(function(){sequential(action);}, 20); 
else action(); 
} 

function send(message){ 
    busy = true; 
    var request = new XMLHttpRequest(); 
    request.open("POST", "owlapi", true); 
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
    request.send(message); 
    request.onreadystatechange = function() {busy = false;}; 
} 
1
while(busy) 
     setTimeout(function(){sequential(action);}, 10); 

setTimeoutはブロックされません。すぐに戻り、ループが続行されます。 Javascriptはシングルスレッドなので、このループは実行を継続し、他のコードの実行を防ぎます。つまり、ビジー状態がループを終了するためにfalseに設定されることはありません。

ajaxコールを待っていると仮定すると、ある種のキューを使用してから、ajaxコールのコールバックで次の要求を実行する可能性が高くなります。

1

あなたのJavaScriptがあなたのサーバーにajaxコールを発信していると推測します。

次々に呼び出す必要がある場合は、javascriptコードを取得して、次の要求を行う前に1回の呼び出しで結果が返るまで待機するようにフックを設定する必要があります。

このような目的で、jQueryのようなjavascriptツールキットを使用することをおすすめします。このような問題は、解決しやすくなります。 jQueryのすべてのajaxメソッドは、少なくともクエリが完了したときに呼び出されるコールバックを受け取ります。 jQuery.ajax()のためには、

$.ajax(...).done(function() { 
    // This part will be run when the request is complete 
}); 

そして.load()のために行くことができます:

$("#my_element").load(url,data,function() { 
    // This part will be run when the request is complete 
});