2011-01-25 36 views
7

Xin chào Tôi đang làm một trang web di chuyển theo chiều ngang như: http://vanityclaire.com/Queue AJAX gọi

Tuy nhiên, thay vì phải một tập tin HTML lớn, sau khi load của trang chủ, tôi ajaxing trong những đứa trẻ của gia đình, sử dụng jQuery. load().

Hiện tại, tôi cho từng div và ajax trong đó url nằm trong tiêu đề. Nhưng AJAX trả về theo thứ tự, và khi tôi thêm nhiều trang hơn, không ưa thích spanging máy chủ với hơn 30 yêu cầu http: //.

Làm cách nào để thực hiện các cuộc gọi AJAX một cách đồng bộ, tức là đợi người đầu tiên quay lại trước yêu cầu khác hoặc thậm chí gửi hai lần một lần.

Tôi đã bị cọ rửa và không thể tìm ra những gì tôi cần.

Đây là HTML của tôi:

<div id="mainLayout" class="fullwidth scrollArea"> 
    <div class="scrollItems"> 
     <div id="page-1" class="scrollItem" title="/"> 
     <div>HOME PAGE CONTENT</div> 
     </div> 
     <div id="page-2" class="scrollItem" title="/Page2.html"> 
     <div class="loading"> </div> 
     </div> 
     <div id="page-3" class="scrollItem" title="/Page3.html"> 
     <div class="loading"> </div> 
     </div> 

     <div id="page-4" class="scrollItem" title="/Page4.html"> 
     <div class="loading"> </div> 
     </div> 
     <div id="page-5" class="scrollItem" title="/Page5.html"> 
     <div class="loading"> </div> 
     </div> 
    </div> 
    </div> 

Và JS của tôi:

function s_loadingInitialPages() { 
    var loadingItems = new Array(); 
    $(".scrollArea .scrollItem").each(function() { 
     if ($(this).attr('title') != '/') { 
      var oDelem = $(this); 
      loadingItems.push(oDelem); 
      //alert('test'); 
     } 
    }); 

    for (i = 0; i < loadingItems.length; i++) { 
     // title attribute is the URL to get 
     var ajaxURL = loadingItems[i].attr("title") + '?ajaxPageContent='; 
     $(loadingItems[i]).load(ajaxURL); 

    } 
} 

Có một plugin Tôi chỉ có thể tiếp tục bổ sung chức năng để một hàng đợi, và để có thể xử lý nó?

+0

nếu u gửi yêu cầu đồng bộ, trình duyệt của bạn sẽ đóng băng. Tôi đề nghị các cuộc gọi không đồng bộ lồng nhau. – Sid

Trả lời

18

Bí quyết là sử dụng các cuộc gọi lại. Bạn thực hiện một cuộc gọi ajax và gọi lại thành công của nó, bạn thực hiện cuộc gọi tiếp theo.

Để thực hiện việc này, chỉ cần thêm tất cả vào hàng đợi và có trình bao bọc xung quanh nó gửi từng cái một.

Tôi đã viết một vài ngày trước. Tôi sẽ chỉ cho bạn một triển khai trong một giây.

// Buffer class. Has a public append method that expects some kind of Task. 
// Constructor expects a handler which is a method that takes a ajax task 
// and a callback. Buffer expects the handler to deal with the ajax and run 
// the callback when it's finished 
function Buffer(handler) { 
    var queue = []; 

    function run() { 
     var callback = function() { 
      // when the handler says it's finished (i.e. runs the callback) 
      // We check for more tasks in the queue and if there are any we run again 
      if (queue.length > 0) { 
        run(); 
      } 
     } 
     // give the first item in the queue & the callback to the handler 
     handler(queue.shift(), callback); 
    } 

    // push the task to the queue. If the queue was empty before the task was pushed 
    // we run the task. 
    this.append = function(task) { 
     queue.push(task); 
     if (queue.length === 1) { 
      run(); 
     } 
    } 

} 

// small Task containing item & url & optional callback 
function Task(item, url, callback) { 
    this.item = item; 
    this.url = url; 
    this.callback = callback 
} 

// small handler that loads the task.url into the task.item and calls the callback 
// when its finished 
function taskHandler(task, callback) { 
    $(task.item).load(task.url, function() { 
     // call an option callback from the task 
     if (task.callback) task.callback(); 
     // call the buffer callback. 
     callback(); 
    }); 
} 

// create a buffer object with a taskhandler 
var buffer = new Buffer(taskHandler); 

for (i = 0; i < loadingItems.length; i++) { 
    // title attribute is the URL to get 
    var ajaxURL = loadingItems[i].attr("title") + '?ajaxPageContent='; 
    buffer.append(new Task(loadingItems[i], ajaxURL)); 
} 

Ví dụ về mã tường. Chỉ cần thực hiện Nhiệm vụ và Trình xử lý của riêng bạn. Bộ đệm sẽ hoạt động miễn là trình xử lý gọi đối số thứ hai (gọi lại) khi nó xử lý xong nhiệm vụ.

Sau đó, chỉ cần chuyển nó một nhiệm vụ và một trình xử lý. Trình xử lý thực hiện ajax và gọi hàm gọi lại từ bộ đệm khi ajax trả về.

Ví dụ cụ thể của bạn nếu những gì tải của bạn mất một thời gian dài thì điều này sẽ mất một thời gian dài để tải tất cả 30. Điểm của ajax là để máy chủ làm công cụ song song.

Một giải pháp tốt hơn rất nhiều trong trường hợp của bạn là thực hiện 30 yêu cầu và sau đó nắm bắt kết quả và đảm bảo kết quả từ cuộc gọi ajax của bạn chỉ được nối vào vị trí theo thứ tự. Điều này liên quan đến việc sử dụng $ .ajax và thêm theo dõi thứ tự bằng cách nào đó.

Bằng cách đó, máy chủ sẽ thực hiện nhanh nhất có thể và bạn có thể quản lý nó theo thứ tự khi bạn nhận được. Ngoài ra, nếu những thứ bạn làm nhanh thì xếp hàng chúng trong một bộ đệm không bị phạt.

+0

+1 cho ý tưởng tuyệt vời. – rubayeet

+0

+1. Đây là cách điều trị đầy đủ hơn về phương pháp này - http://www.dustindiaz.com/async-method-queues/ –

+1

Chúc mừng Raynos, có vẻ tốt và hiểu nó một cách đáng ngạc nhiên. Cũng tìm thấy http://www.protofunc.com/scripts/jquery/ajaxManager/ này - có một vài tùy chọn khác. –

1

Hầu hết các trình duyệt có thể xử lý từ 6 yêu cầu ajax đồng thời trở lên cho một tên miền duy nhất.
http://www.browserscope.org/?category=network&v=top

Nếu tập lệnh của bạn đặt 30 yêu cầu ajax cùng một lúc, 6 yêu cầu đầu tiên sẽ được thực hiện rất nhanh. Sau đó, trình duyệt có thể bắt đầu gán thời gian chờ tùy ý lên đến 5 giây. Chrome là một ví dụ điển hình về hành vi này.

Yêu cầu 1-6 trở lại sau 5 phút.

Yêu cầu 7-12 trở lại sau 5,005 mili giây.

Yêu cầu 11-18 trả lại trong 10,005 mili giây.

Yêu cầu 19-24 trở lại trong 15,005 mili giây.

Yêu cầu 25-30 trở lại trong 20,005 mili giây.

Tôi khuyên bạn nên xây dựng một hàng đợi các hàm callback để xử lý tất cả các yêu cầu ajax của ứng dụng và xử lý không quá 6 trong số đó tại một thời điểm.

var ajaxCownt = (ajaxCownt == null ? 0 : ajaxCownt); // Make limit globally accessible. 
 
var ajaxKue = (ajaxKue == null ? [] : ajaxKue); // Make queue globally accessible. 
 

 
function doMyAjaxRequest() { 
 
console.log("doing ajax request."); 
 
// Implement ajax request, here. 
 
} 
 

 
for (var i = 1;i <= 30;i++) { 
 
ajaxKue.push(function() { doMyAjaxRequest() }); // Add request to queue. 
 
} 
 

 
while (ajaxCownt != null && ajaxCownt < 6 && ajaxKue != null && ajaxKue.length && ajaxKue.length > 0) { 
 
ajaxCownt++; 
 
console.log("incrementing pending ajax requests counter by 1."); 
 
ajaxKue.shift().call(); 
 
}; 
 

 
// Register an event to detect when an ajax request completes. 
 
// Allow for an additional ajax request to be processed. 
 
$(document).ajaxComplete(function() { 
 
    if (ajaxCownt && ajaxCownt > 0) { 
 
     ajaxCownt--; 
 
     console.log("decrementing pending ajax requests counter by 1."); 
 
    } 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>