2011-01-17 11 views
13

Me parece estar teniendo algunos problemas con la fabricación de HEAD solicitudes, y la preservación de la integridad de los datos en una matriz.petición HEAD Ajax a través de Javascript/jQuery

Teniendo en cuenta este fragmento:

var imageTemp = Array(); 

$('*') 
    .each(function(index){ 
     if($(this).css('background-image') != 'none'){ 
      imageTemp.push($(this).css('background-image').slice(5, -2)); 
     } 
    }); 

capturo las direcciones URL de todos los fondo-imágenes en una página determinada. Ahora, tratando de agarrar el tamaño de cada imagen a través de HEAD solicitudes de Content-Length, utilizo este fragmento:

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')]); 
     } 
    }); 
} 

Sin embargo, cuando yo tiro imageData través console.log, que cada elemento (que debería ser una matriz que contiene la URL y el contenido de longitud) termina como [undefined, XXXX] donde XXXX es siempre el tamaño de la última solicitado Content-Length

estoy perplejo, a pesar de que parece ser un/tema de alcance momento. ¿Tengo algún tipo de condición racial aquí?

+4

En lugar de una variable 'ajaxSizeRequest', se puede usar el segundo parámetro' de devolución de llamada Success'. – SLaks

Respuesta

17

El problema es que las variables individuales i y ajaxSizeRequest siendo capturados por la función de devolución de llamada son las mismas variables para todas las instancias de la función de devolución de llamada. Creo que si se llama a una función y pasa la variable de índice a la misma y, al mismo tiempo, alcance de la variable de petición de forma local a la función en sí utilizar el parámetro de respuesta del controlador de hecho, que debe terminar con las variables independientes capturados por la devolución de llamada. Luego debe hacer referencia a cada elemento de la matriz y a cada variable de respuesta correctamente.

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')]); 
    }); 
} 
+0

Muchas gracias ** tvanfosson **; Eso funciona como un encanto. Hice 'updateImageData' anonymous para evitar la contaminación de mi script. – Dan

+0

¡evite usar 'success', evite el desorden de códigos !, use' .done (function (text, status, xhr) {......}; 'en su lugar –

+0

@EladKarako - respuesta muy antigua, he actualizado para reflejar la mejor práctica actual. – tvanfosson

0

usted tiene un solo i variable que es compartido por todas las devoluciones de llamada.
Desde AJAX es asíncrona, todas las devoluciones de llamada se ejecutan después de su bucle se termina, y todos ellos reciben la misma i.

Para solucionar este problema, tiene que mover la llamada AJAX en una función separada que lleva i como parámetro.
Por lo tanto, cada uno de devolución de llamada obtendrá un parámetro independiente i.

2

parece que su i isnt correctamente cerrado en

, además, no se puede utilizar ajaxSizeRequest porque también está apuntando a una sola petición (probablemente la última, ya que el ciclo se ejecutará muy rápido)

acaba de envolver su función de devolución de success de la siguiente manera, el cambio de la referencia a ajaxSizeRequest:

success: (function(i){ 
    return function(data,status,xhr){ 
    imageData.push([imageTemp[i], xhr.getResponseHeader('Content-Length')]); 
    }; 
})(i) 
1

puede alcance que de este modo:

success: function(i){ 
    return function(message){ 
     imageData.push([imageTemp[i], ajaxSizeRequest.getResponseHeader('Content-Length')]); 
    } 
}(i) 
Cuestiones relacionadas