2011-08-06 8 views
3

可能性の重複:
Can't access global variable in jQuery $.get within function

これはおそらく、初心者の問題ですが、ここではそれが行く:私は宣言プレビューと呼ばれるグローバル変数AJAXを使用して、json配列を取得してループします。繰り返しごとに、別のAJAX呼び出しを行って文字列を取得し、それをグローバル変数に追加します。

しかし、第2のAJAX呼び出しの後にグローバル変数を印刷することは私に「空の文字列」(私は間違いなく戻って二AJAX呼び出しから文字列を取得しています)を提供します。

var preview; 
$("#some-button").click(function(e){ 
    e.preventDefault(); 
    var companies = "blahblahblah"; 

    $.ajax({ 
     url: "tracklink/getemails.php", 
     type: "POST", 
     data: "companies=" + companies, 
     dataType: "json", 
     success: function(databack) { 
      if (databack) { 
       for (i=0; i<databack.length; i=i+1) { 
        preview = ""; 
        $("#selected-clip-list li").each(function(){ 
         $.ajax({ 
          url: "tracklink/cksum.php", 
          type: "POST", 
          data: "video_id=" + $(this).attr("clip_id") + "&addr=" + databack[i].email_address, 
          success: function (msg) { 
           if (msg) { 
            preview += msg; 
           } 
           //this works 
           //console.log(preview); 
          } 
         }); 
        }); 
        //doesn't work 
        console.log(preview); 
       } 
      } 
     } 
    }); 
}); 

私は "空の文字列" を取得していますなぜすべてのアイデア:

ここでは、コードですか?

多くのありがとうございます。

+0

'$ .ajax()'に 'async:false'を設定すると、コールバック関数で変数にアクセスできるようになります。 – Quasdunk

答えて

5

アヤックス非同期ですので。このライン:

//doesn't work 
console.log(preview); 

は、応答が処理される前に実行されます。これが応答を処理するコールバック関数(success:)を提供する理由です。

応答に対処する必要があるすべてのコードは、内部またはコールバックから呼び出さなければなりません。

それは(それがアクセス可能であるため)コールバックでアクセス可能ではないpreviewとは関係ありません。

更新:あなたはDeferred objectsを使用してこの問題を解決することができます:

success: function(databack) { 
     if (databack && databack.length > 0) { 
      var deferred = $.Deferred(); 

      preview = ""; 
      for (i=0; i<databack.length; i=i+1) { 
       $("#selected-clip-list li").each(function(){ 
        deferred = deferred.pipe($.ajax({...})); 
       });     
      } 
      deferred.then(function() { 
       console.log(preview); 
      }); 
     } 
    } 

応答が正しい順序でpreviewに追加されるように、これはAjaxの順次リクエスト(しかし、非ブロッキング)を実行します。しかし実際には、どのデータを収集したいのですか?previewは100%わかりません。このネストされたforループが正しいと確信していますか?あなたはAjaxリクエストの順序を気にしない場合は

、あなたもこれを行うことができます。

var deferreds = []; 
for (i=0; i<databack.length; i=i+1) { 
    $("#selected-clip-list li").each(function(){ 
     deferreds.push($.ajax({...})); 
    });     
} 
$.when.apply($, deferreds).then(function() { 
    console.log(preview); 
}); 
+0

ありがとうございます。 – Shmoyko

+0

@ user374407:ようこそ。 –

0

を不幸にAJAX要求が非同期であるので、あなたはそれが期待通りに動作しないこと。基本的には、プレビューを空に設定し、一連の要求をディスパッチして、空の変数を出力します。要求は後で完了して記入されますが、すでに印刷されています。

ここでは、あなたが持っていたものの基本的な再加工版ですが、少し良くなりました。これらの関数のそれぞれは、ajaxリクエストが完了する前に返され、すべてのリクエストが完了すると、次のリクエストが呼び出されることを覚えておいてください。これにより、醜いグローバル変数を使用することさえ回避されます。

+0

ありがとうございます。それほど感謝します – Shmoyko

関連する問題