2011-01-25 5 views
7

안녕하세요 저는 같은 수평 스크롤 웹 사이트를하고있는 중이 야 호출합니다. 하중().큐 AJAX는

현재 제목에있는 URL에있는 각 div와 ajax에 대해. 하지만 AJAX는 잘못된 순서로 돌아오고, 더 많은 페이지를 추가하면 30 + http : // 요청을 가진 서버를 스패닝하지 않습니다.

AJAX 호출을 동기식으로 수행하려면 어떻게해야합니까? 즉, 요청이 다른 요청보다 먼저 복귀 할 때까지 기다리거나 한 번에 두 개씩 보냅니다.

나는 수색을하고 있었고, 내가 필요한 것을 알아낼 수 없었다.

<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> 

그리고 내 JS :

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); 

    } 
} 

난 그냥 큐에 기능을 계속 추가, 그리고 그것을 처리 할 수있는 플러그인이 있나요

이 내 HTML입니까?

+0

유 동기 요청을 보낼 경우, 브라우저가 정지됩니다. 내포 된 비동기 호출을 제안합니다. – Sid

답변

18

트릭은 콜백을 사용하는 것입니다. 당신은 하나의 아약스 콜을하고 성공 콜백에서 다음 콜을한다.

이렇게하려면 모든 큐에 큐를 추가하고 하나씩 차례로 보내는 래퍼가 있어야합니다.

나는 며칠 전에 썼다. 구현을 잠시 후에 보여 드리겠습니다.

// 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)); 
} 

코드 벽에 사과드립니다. 그냥 자신의 작업 및 처리기를 구현하십시오. 버퍼는 태스크 처리가 끝나면 핸들러가 두 번째 인수 (콜백)를 호출하는 한 계속 작동합니다.

그런 다음 작업과 처리기를 전달하십시오. 핸들러는 ajax를 수행하고 ajax가 리턴 할 때 버퍼에서 콜백을 호출합니다.

로딩 시간이 오래 걸리는 경우 30 개를 모두로드하는 데 시간이 오래 걸릴 수 있습니다. 아약스의 요점은 서버가 동시에 처리하도록하는 것입니다.

30 가지 요청을 한 다음 결과를 확인하고 아약스 호출의 결과가 순서대로 dom에만 추가되는지 확인하는 것이 훨씬 더 나은 해결책입니다. 여기에는 $ .ajax를 사용하고 어떻게 든 주문 추적을 추가하는 작업이 포함됩니다.

그런 식으로 서버가 가능한 한 빨리 서버를 수행하고 서버를 확보하면 순서대로 서버에 배치 할 수 있습니다. 또는 수행중인 작업이 빠르면 버퍼에 대기열에 넣을 때 페널티가 발생하지 않습니다.

+0

+1 좋은 생각. – rubayeet

+0

+1. 이 방법의 더 철저한 치료법은 다음과 같습니다 - http://www.dustindiaz.com/async-method-queues/ –

+1

환호성 Raynos, 좋아 보이고 놀랍게도 이해합니다. 또한 http://www.protofunc.com/scripts/jquery/ajaxManager/에서 찾을 수 있습니다 - 몇 가지 옵션이 있습니다. –

1

대부분의 브라우저는 단일 도메인에 대해 6 개 이상의 동시 ajax 요청을 처리 할 수 ​​있습니다.
http://www.browserscope.org/?category=network&v=top

스크립트가 30 개의 ajax 요청을 한꺼번에 처리하는 경우 처음 6 개 요청은 매우 빠르게 처리됩니다. 그 후 브라우저는 최대 5 초의 임의 대기 시간을 할당하기 시작할 수 있습니다. 크롬은 이러한 행동의 대표적인 예입니다.

요청 1-6은 5ms 후에 반환됩니다.

요청 7-12은 5,005 ms에 반환합니다.

요청 11-18은 10,005 MS에서 반환됩니다.

요청 19-24 15,005 MS에서 반환.

요청 25-30은 20,005 MS에서 반환됩니다.

모든 응용 프로그램의 ajax 요청을 처리하고 한 번에 6 개를 처리 할 수있는 함수 콜백 대기열을 작성하는 것이 좋습니다.

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>