2011-01-17 22 views
13

Mam pewne problemy z wysyłaniem żądań HEAD i zachowywanie integralności danych w tablicy.Żądanie Ajax HEAD za pośrednictwem Javascript/jQuery

Biorąc pod uwagę ten fragment:

var imageTemp = Array(); 

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

I przechwytywania adresów URL wszystkich obrazów tła na danej stronie. Teraz, próbując chwycić wielkość każdego obrazu poprzez HEAD wniosków o Content-Length, używam ten fragment:

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

Jednak, kiedy zrzucić imageData poprzez console.log, że każdy element (który powinien być tablicą zawierającą adres URL i treść długości) kończy jako [undefined, XXXX] gdzie XXXX jest zawsze wielkość ostatni wniosek Content-Length

Jestem zakłopotany, choć wydaje się być rozrządu/scoping problem. Czy mam tutaj jakiś rodzaj wyścigu?

+4

Zamiast 'zmiennej ajaxSizeRequest', można użyć drugiego parametru Opcja' success' oddzwonienia za. – SLaks

Odpowiedz

17

Problemem jest to, że pojedyncze zmienne i i ajaxSizeRequest rejestrowany przez funkcję wywołania zwrotnego są takie same zmienne, w każdym przypadku w funkcji połączenia zwrotnego. Myślę, że jeśli wywołasz funkcję i przekazujesz do niej zmienną indeksową, a jednocześnie zakres zmienna żądania lokalnie do samej funkcji użyj parametru odpowiedzi wykonanego programu obsługi, powinieneś skończyć z niezależnymi zmiennymi przechwytywanymi przez wywołanie zwrotne. Powinien wówczas poprawnie odwoływać się do każdego elementu tablicy i każdej zmiennej odpowiedzi.

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

Dzięki za dużo ** tvanfosson **; To działa jak urok. Zrobiłem anonimowy updateImageData, aby uniknąć zanieczyszczenia mojego skryptu. – Dan

+0

unikaj używania 'sukcesu', zapobiegaj bałaganiu kodu !, użyj' .done (funkcja (tekst, status, xhr) {......}; 'zamiast. –

+0

@EladKarako - dość stara odpowiedź, zaktualizowałem aby odzwierciedlać obecną najlepszą praktykę – tvanfosson

0

Masz jedną zmienną i, która jest wspólna dla wszystkich wywołań zwrotnych.
Ponieważ AJAX jest asynchroniczny, wszystkie wywołania zwrotne są uruchamiane po zakończeniu pętli i wszystkie mają ten sam i.

Aby to naprawić, należy przenieść wywołanie AJAX do oddzielnej funkcji, która przyjmuje jako parametr i.
W ten sposób każde wywołanie zwrotne otrzyma oddzielny parametr i.

2

wygląda jak i isnt prawidłowo zamknięte w

ponadto nie można używać ajaxSizeRequest ponieważ zbyt wskazuje tylko jeden wniosek (prawdopodobnie ostatni, bo pętla wykona się bardzo szybko)

prostu owinąć funkcji zwrotnej success następująco zmieniając odniesienie do ajaxSizeRequest:

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

można zakres Lubię tak:

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