HEAD
リクエストを作成し、配列内のデータの整合性を維持する際に問題が発生しているようです。
このスニペットを考えると:
var imageTemp = Array();
$('*')
.each(function(index){
if($(this).css('background-image') != 'none'){
imageTemp.Push($(this).css('background-image').slice(5, -2));
}
});
特定のページのすべての背景画像のURLをキャプチャします。次に、Content-Length
のHEAD
リクエストを介して各画像のサイズを取得しようとするため、次のスニペットを使用します。
var imageData = Array();
for(var i = 0; i < imageTemp.length; i++){
ajaxSizeRequest = $.ajax({
type: "HEAD",
async: true,
url: imageTemp[i],
success: function(message){
imageData.Push([imageTemp[i], ajaxSizeRequest.getResponseHeader('Content-Length')]);
}
});
}
ただし、imageData
をconsole.log
を介してダンプすると、各要素(URLとコンテンツの長さを含む配列である必要があります)は[undefined, XXXX]
となり、XXXX
は常に最後にリクエストされたサイズですContent-Length
タイミング/スコープの問題のようですが、困惑しています。ここで一種の競合状態が発生していますか?
問題は、コールバック関数によってキャプチャされている単一の変数i
およびajaxSizeRequest
が、コールバック関数のすべてのインスタンスで同じ変数であることです。関数を呼び出してそれにインデックス変数を渡すと、同時に、 リクエスト変数を関数自体にローカルにスコープします doneハンドラーの応答パラメーターを使用すると、コールバックによってキャプチャされた独立変数になるはずです。次に、各配列要素と各応答変数を正しく参照する必要があります。
var imageData = Array();
for(var i = 0; i < imageTemp.length; i++){
updateImageData( i );
}
function updateImageData( i )
$.ajax({
type: "HEAD",
async: true,
url: imageTemp[i],
}).done(function(message,text,jqXHR){
imageData.Push([imageTemp[i], jqXHR.getResponseHeader('Content-Length')]);
});
}
i
が適切に閉じ込められていないようです
さらに、ajaxSizeRequest
も使用できません。これも1つの要求のみを指しているためです(おそらくループが非常に高速に実行されるため、最後の要求です)。
success
コールバック関数を次のようにラップし、参照をajaxSizeRequest
に変更します。
success: (function(i){
return function(data,status,xhr){
imageData.Push([imageTemp[i], xhr.getResponseHeader('Content-Length')]);
};
})(i)
あなたは私が好きなスコープにすることができます:
success: function(i){
return function(message){
imageData.Push([imageTemp[i], ajaxSizeRequest.getResponseHeader('Content-Length')]);
}
}(i)
まだこれで問題があり、この投稿がすでに5年前のようなものである場合、回答のより「モダン」なバージョンをここに示します。let
ではなくvar
を使用してください元の投稿のfor
ループ。
情報: ES6で「var」キーワードを使用する理由はありますか? および: MDN-Let構文
すべてのコールバックで共有される単一のi
変数があります。
AJAXは非同期であるため、すべてのコールバックはループの終了後に実行され、すべて同じi
を取得します。
これを修正するには、AJAXの呼び出しをパラメータとしてi
を使用する別の関数に移動する必要があります。
したがって、各コールバックは個別のi
パラメータを取得します。