2012-02-22 22 views
0

私はいくつかの機能を実行するスクリプトを作成しており、関数が完了するとユーザーを更新したいと思います。私は$.ajax()の呼び出しを、前回の呼び出しの各呼び出しで入れ子にしました。successブロック。オーダーされた非同期AJAXコール

各ループに合計4回の呼び出しがあります。 scan_1からscan_4までとしましょう。 successブロックのscan_1scan_2などと呼ばれ、チェーンの下にあります。

たとえば、3つのオブジェクトをループしているとします。

  • ループ2

    ループ1

    • scan_1
    • scan_2
    • scan_3
    • scan_4

    :私は、プロセスはこのように行きたいですscan_1

  • scan_2
  • scan_3
  • scan_4

ループ3

  • scan_1
  • scan_2
  • scan_3
  • scan_4

問題は、最初にすべてのscan_1コールが実行されていることです。私は何かを欠いているに違いないが、私はそれを理解しているようには見えない。アドバイスをいただければ幸いです。参考のため

は、ここscan_1のスニペットは、(無関係なものが切り取ら)である:

for(var i = 1; i <= 3; i++) 
{ 
    $.ajax({ 
     type:  'GET', 
     url:  url, 
     data:  'do=scan&step=1&' + string, 
     dataType: 'json', 
     success: function (result) 
     { 
      if(result.proceed == 'true') 
      { 
       $('#scan_progress').append(result.message); 
       scan_2(); 
      } 
      else 
      { 
       $('#scan_progress').append(result.message); 
      } 
     } 
    }); 
} 

思考?

ありがとうございます。

答えて

3

はあなたのような音to use jQuery deferredが必要です。基本的には、複数のイベントハンドラをjQuery Ajaxオブジェクトに連結することができ、コールバックが呼び出されるタイミングをより細かく制御できます。

さらに読書:

+0

これは私の答えだと思います。本当にありがとう! – SenorAmor

+0

@SenorAmorあなたは何を使用して終了しましたか?私の答えはあなたのコードで遅延オブジェクトを使用する方法の例を示しているからです。 – Jasper

+0

@SenorAmorあなたが使ったことを投稿して、あなたが持っていたものと同じ質問でここに来る他の誰もがあなたが使ったものを見ることができるようにするなら、コミュニティにとっては良いでしょう。 –

1

これは非同期です。将来的には「成功」が発生します。スクリプトは応答するのを待つことはありません。ループ内で3つのリクエストを発しているので、それらはすべて「scan1」になります。

各リクエストの完了時に「scan_2」が呼び出されます。

イベントの順序を制御する場合は、要求を同期に変更します。

+0

私は理解していますが、同期呼び出しがブラウザをロック(Firefox用に保存)し、ループ全体が完了するまで情報を出力しないという問題があります。これは基本的にテキストベースのローディングバーです。私は、ブラウザーをフリーズさせずにやりたいことを実行する同様のスクリプトがあることを知っています。私はちょうど方法を知らない。 – SenorAmor

+0

次に、「イベントキュー」を作成する必要があります。一度に1つの要求を発行してから、キュー内の次のイベントを取得してから消してください。 –

1

あなたはすぐに3回のajaxコールを送信することから始めます。

SCAN1(ループ1)
SCAN1(ループ2)
SCAN1(ループ3)各々が1つの完了をスキャンするとき

、それがその後のスキャン2'S、次いで3が呼び出されるスキャン。

あなたは実際に何をしたがっていますか?ループ1の1,2および3をスキャンし、次にループ2の1,2および3をスキャンし、次にループ3の1および2をスキャンしますか?それには、より多くのネストや、遅延オブジェクトが必要です。代わりに、各$.ajax()呼び出しに対してsuccessコールバックを使用しての

1

、あなたは、アレイ内のAJAXリクエスト(そのjqXHRオブジェクト)の各セットを保存し、解決するためにそれらのすべてを待つことができます。

function scan_1() { 

    //setup array to store jqXHR objects (deferred objects) 
    var jqXHRs = []; 
    for(var i = 1; i <= 3; i++) 
    { 

     //push a new index onto the array, `$.ajax()` returns an object that will resolve when the response is returned 
     jqXHRs[jqXHRs.length] = $.ajax({ 
      type:  'GET', 
      url:  url, 
      data:  'do=scan&step=1&' + string, 
      dataType: 'json' 
     }); 
    } 

    //wait for all four of the AJAX requests to resolve before running `scan_2()` 
    $.when(jqXHRs).then(function() { 
     if(result.proceed == 'true') { 
      scan_2(); 
     } 
    }); 
} 
0

私は、SharePointのWebサービスで多額の作業同様の問題を持っていた - あなたは、多くの場合のための入力を生成するために、複数のソースからデータを取得する必要があります単一のプロセス

私はこの種の機能をAJAX抽象化ライブラリに組み込みました。完了時に一連のハンドラを起動するリクエストを簡単に定義できます。ただし、各リクエストは複数のhttp呼び出しで定義できます。ここで、コンポーネント(および詳細なドキュメントが)です:

// The handler function 
function AddUp(Nums) { alert(Nums[1] + Nums[2] + Nums[3]) }; 

    // Create the pool 
myPool = DP_AJAX.createPool(); 

    // Create the request 
myRequest = DP_AJAX.createRequest(AddUp); 

    // Add the calls to the request 
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [5,10]); 
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [4,6]); 
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [7,13]); 

    // Add the request to the pool 
myPool.addRequest(myRequest); 

DPAJAX at DepressedPress.com

この単純な例では、3つの呼び出しとシングルハンドラに、呼び出しのために、その情報を渡して要求を1つ作成しますこのメソッドが提供されている他の多くのソリューションとは異なり、このメソッドは呼び出しのシングルスレッド化を強制しません - それぞれが環境が許す限り速く(またはゆっくりと)実行されますが、単一のハンドラはすべてが完了したときにのみ呼び出されます。また、サービスが少し不安定な場合は、タイムアウト値と再試行の設定もサポートされます。

私は非常に便利で(コードの観点からは非常に理解しやすい)ことがわかりました。連鎖がなくなり、呼び出し回数が増えず、出力が節約できます。ちょうど "それを設定し、それを忘れる"。

関連する問題