2013-04-05 4 views
6

비동기 아약스 요청을 12 회 수행하고 모든 것이 끝나기를 기다렸다가 집계 된 정보를 반환하는 함수를 작성하고 싶습니다. Like :비동기 아약스 요청이 완료 될 때까지 기다려주십시오.

function countHealthy(urls) { 
    var healthy = 0; 
    for (var i = 0; i < urls.length; ++i) { 
    $.ajax({url: urls[i], async: true, id: i}) 
    .done(function (data) { ++healthy; }); 
    } 
    // Wait for all ajax to finish. 
    return healthy; 
} 

추 신 : ++ 건강한 스레드는 안전합니까?

답변

6

자바 스크립트에 스레드가 없으므로 스레드 안전성에 문제가 없습니다. return 문이 문제이며, 완료시 ajax 호출이 실행하는 콜백으로 이동해야합니다. 아약스는 비동기로 발생하기 때문에 코드가 나타날 때 return 문은 모든 요청이 반환되기 전에 실행됩니다.

query deferreds을 확인해보십시오.이 유형의 것으로 태어난 것 같습니다. 해당 링크에서 직접

function doAjax() { 
    return $.get('foo.htm'); 
} 

function doMoreAjax() { 
    return $.get('bar.htm'); 
} 

$.when(doAjax(), doMoreAjax()) 
    .done(function() { 
    console.log('I fire once BOTH ajax requests have completed!'); 
    }) 
    .fail(function() { 
    console.log('I fire if one or more requests failed.'); 
    }); 

약간의 리팩터링을 사용하면 약 2 분 내에 구현할 수 있습니다.

또는 서버를 제어하는 ​​경우 한 번의 요청으로 모든 검사를 수행하는 서버 끝점을 만들 수 있습니다.

1

이 작업을 수행 할 수 있습니다

var urls= ['url1', 'url2', 'url3', 'url4']; 
function doTheUrl() { 
    if (urls.length === 0) { 
     alert('All urls are done now.'); 
     return; 
    } 

    var url = urls.pop(); 
    $.ajax({ 
     url: "/DoTheJob", 
     complete: function() { 
      doTheUrl(); 
     } 
    }); 
}; 
+0

당신은 "when.apply"작동하는 방법의 아이디어를 얻을 수 있습니다, 사실 난이 작동합니다 생각하지 않습니다. 함수의 마지막에는 암시적인'return'이 있습니다. 그래서 $ .ajax 호출이 스택에 놓이면 모든 것이 계속 움직이고 함수는 종료된다. 나는 지금 downvote 것입니다. – the0ther

0

어쩌면 당신이 시도 할 수 있습니다. 난 단순히 빈 while 루프를 실행하므로 모든 ajax 호출이 반환 될 때까지 return 문이 중단되지 않습니다.

function countHealthy(urls) { 
    var healthy = 0; 
    var urlCount = urls.length; 
    var numberOfAjaxCallsReturned = 0; 
    for (var i = 0; i < urls.length; ++i) { 
    $.ajax({url: urls[i], async: true, id: i}) 
     .done(function (data) { 
       ++healthy; 
       numberOfAjaxCallsReturned++; 
     }); 
    } 
    while(numberOfAjaxCallsReturned!=urlCount) 
    { 
    } 
    return healthy; 
} 
+1

매우 나쁜 성능이 내 의견에 유용하지 않습니다. –

0

복잡한 페이지가있는 경우 반환 할 비동기 호출을 추적하고 기다리는 것이 좋습니다. 이것은 다른 비 crucual 호출이 실행 중일 수 있기 때문입니다.

간단한 페이지의 경우 확인하고 아무 전화도 들리지 않을 수 있습니다. 이 jQuery 스크립트는 매 분기마다 현재 비동기 요청이 있는지 확인합니다. 아무 것도 없으면 계속 진행할 것입니다. 모든

var WaitForAjax = function() 
    { 
     if (jQuery.active == 0){ 
     } 
     else 
     { 
      setTimeout(WaitForAjax, 250); 
     } 
    } 

    function RunIt() 
    { 
     //IssueAjaxCalls would be where you make all your Ajax calls. 
     IssueAjaxCalls(); 

     WaitForAjax(); 

     //The KeepGoing function won't get called until there are no more Ajax calls pending. 
     KeepGoing(); 
    } 
0

먼저 당신은 당신의 서버 자원을 낭비 조금 보인다 루프 각 아약스 요청을하고 있습니다. 그 함수가 많이 호출되는 경우, 코드 을 리팩토링하여 가능한 한 적은 수의 쿼리로 만들 것을 제안합니다.

은 어쨌든, 여기에 그것을 밖으로 시도 할 기회가 없었나요 내가 그것을

function countHealthy(urls) { 

    var healthy = 0; 
    var reqs = []; 

    for (var i = 0; i < urls.length; ++i) { 
     reqs.push(
      $.ajax({ 
       url: urls[i], 
       id: i 
      }) 
     ); 
    } 
} 


$.when.apply($, reqs).then(function() { 
    // On success 
    ++healthy; 
}).fail(function() { 
    // When failed 
}).always(function() { 
    // this will be run no matter the outcome 
}); 

을 할 거라고 방법, 그래서 난 변화 등 문법 실수를했는지 확실하지 않습니다 귀하의 코드 조각 :

제거 된 async = true, 이전에 코드 어딘가에 false로 설정했다면 이것을 무시하십시오. source

관련 문제