2011-01-17 48 views
13

Tôi dường như đang gặp phải một số vấn đề với yêu cầu HEAD và bảo toàn tính toàn vẹn của dữ liệu trong một mảng.Yêu cầu HEAD Ajax qua Javascript/jQuery

Với đoạn mã này:

var imageTemp = Array(); 

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

tôi nắm bắt được URL của tất cả các nền-hình ảnh trên một trang nhất định. Bây giờ, cố gắng để lấy kích thước của mỗi hình ảnh qua HEAD yêu cầu Content-Length, tôi sử dụng đoạn mã này:

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

Tuy nhiên, khi tôi đổ imageData qua console.log, tôi từng yếu tố (mà phải là một mảng chứa các URL và độ dài nội dung) kết thúc là [undefined, XXXX] trong đó XXXX luôn luôn là kích thước của yêu cầu mới nhất Content-Length

Tôi bị bối rối, mặc dù nó có vẻ là vấn đề về thời gian/phạm vi. Tôi có một loại tình trạng chủng tộc xảy ra ở đây không?

+4

Thay vì một biến 'ajaxSizeRequest', bạn có thể sử dụng tham số thứ hai 'success' callback của. – SLaks

Trả lời

17

Vấn đề là các biến đơn iajaxSizeRequest bị hàm gọi lại ghi lại là các biến tương tự cho tất cả các phiên bản của hàm gọi lại. Tôi nghĩ nếu bạn gọi hàm và chuyển biến chỉ mục cho nó và, cùng lúc, phạm vi biến yêu cầu cục bộ cho chính hàm sử dụng tham số phản hồi của trình xử lý được thực hiện, bạn sẽ kết thúc với các biến độc lập được gọi lại. Sau đó nó sẽ tham chiếu từng phần tử mảng và từng biến trả lời một cách chính xác.

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

Cảm ơn rất nhiều ** tvanfosson **; Điều đó hoạt động như một sự quyến rũ. Tôi đã ẩn danh 'updateImageData' để tránh gây ô nhiễm cho tập lệnh của mình. – Dan

+0

tránh sử dụng 'thành công', ngăn chặn mã lộn xộn !, sử dụng' .done (hàm (văn bản, trạng thái, xhr) {......}; 'thay thế. –

+0

@EladKarako - câu trả lời khá cũ, tôi đã cập nhật – tvanfosson

0

Bạn có một biến số i được chia sẻ bởi tất cả các cuộc gọi lại.
Vì AJAX không đồng bộ, tất cả các cuộc gọi lại chạy sau khi vòng lặp của bạn kết thúc và tất cả chúng đều giống nhau i.

Để khắc phục điều này, bạn cần di chuyển cuộc gọi AJAX sang một hàm riêng biệt có tham số i làm tham số.
Do đó, mỗi cuộc gọi lại sẽ nhận được thông số i riêng biệt.

2

trông giống như i isnt bạn đóng trong đúng

trong Ngoài ra, bạn không thể sử dụng ajaxSizeRequest vì nó quá được trỏ đến chỉ là một yêu cầu (có lẽ là cuối cùng, bởi vì vòng lặp sẽ thực hiện rất nhanh)

chỉ quấn hàm callback success của bạn như sau, thay đổi tham chiếu đến ajaxSizeRequest:

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

bạn có thể phạm vi tôi thích như vậy:

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