2

私のスクリプトはjQueryを介してAjaxリクエストを作成します。受信したデータは、サーバーサイドスクリプト(php)を介してjson_encodedされます。これはさらに文字列化され、jQueryを使用してparseJSONされ、recordCollectionが生成されます。recordCollectionをループして、コールバック関数のスコープ外で宣言された変数であるrecords配列にプッシュします。

関数は次のようになります。

var records = [] ;
$.getJSON(url, {id : recordid}, function(data) {

 var recordCollection = jQuery.parseJSON(JSON.stringify(data));

 $.each(recordCollection, function(){
  records.push(this);
 });
  console.log(records) // displays all the objects, thus, the above code is right
});  

console.log(records); // displays [] 

上記のように、2回目にレコードをコンソールにログオンすると、空の配列が生成され、2つの結論に至りました。

  1. Javascript配列は値で渡されるため、コールバック関数のスコープ外のレコードはその値を保持しません。

  2. Ajaxは非同期であるため、ajax呼び出しが完了する前にレコードがログに記録されます。したがって、空の初期化されていないレコード配列の値が保持され、コンソールに記録されます。

1が真の場合、レコード配列を初期化するにはどうすればよいですか?

そして、2が真の場合、このAjax呼び出しを同期させる必要がありますか?これにより、値が返されるまでjavascriptブロックが作成されるため、records配列がコンソールに2回目にログオンすると、配列の更新された値が表示されますか?

3つ目は、私がトリックを完全に見逃していて、ここで本当に馬鹿げたことをしていることです。

スクリプト内のさまざまなjavascript関数に渡す必要があり、DOMは基本的にこの結果がデータをロードするのを待つため、ajax呼び出しから返されたデータでrecords配列を設定する必要があります。

みんなありがとう!

4

2 に答える 2

2

あなたはその点で正しいです、ajax呼び出しは非同期です、それ故にAsynchronous Javascript and XML。同期させることはできますが、そうしないでください。アレイを誰でも使用できるようになり、大きな頭痛の種になる可能性があります。

代わりに、ajax呼び出しが完了したときに実行されるinit呼び出しを用意します。

function callback(records) {
  // do stuff with records.
}

$.getJSON(url, {id : recordid}, function(data) {

 var recordCollection = jQuery.parseJSON(JSON.stringify(data));
 callback(recordCollection); 
}); 
于 2012-12-24T21:06:35.300 に答える
1

AjaxはAsynchronousJavaScriptand XML(XMLの部分は忘れてください)の略なので、何が正しいかを推測できると思います;-)

コメント付きの実行順序を追加しました。

var records = [] ;

// 1. send request and return immediately
$.getJSON(url, {id : recordid}, function(data) {

 // 3. response from server is received
 var recordCollection = jQuery.parseJSON(JSON.stringify(data));    
 $.each(recordCollection, function(){
  records.push(this);
 });
  console.log(records)
});  

// 2. print records
console.log(records); 

リクエストを同期させようとしないでください。データが利用可能になった後で何かを行う必要がrecordsある場合は、新しい関数を作成し、値をにプッシュした後にそれを呼び出す必要がありますrecords

于 2012-12-24T21:06:04.040 に答える