2014-02-17 5 views
13

저는 AJAX를 처음 사용하기 때문에 페이지에 많은 링크를 처리하고 각각에 대해 AJAX 호출을 작성하는 사용자 스크립트를 작성하고 있습니다.jQuery AJAX가 루프를 호출합니다.

for (var i = 0; i < linkList.length; i++) 
{ 
    $.ajax({ 
     url: linkList[i].getAttribute("href"), 
     cache: false 
    }).done(function(html) 
    { 
     var hasAppended = false; 
     if (html.indexOf('someStringOnGottenPage') != -1 && !hasAppended) 
     { 
      hasAppended = true; 
      var id = linkList[i].getAttribute("href").substring(linkList[i].getAttribute("href").indexOf('=')); 
      $("#links a[href*='" + id + "']").append(' THIS PAGE CONTAINS SPECIFIED DATA'); 
     } 
    }); 
} 

간단히 말해서, 링크 목록이있는 페이지가 있습니다. 링크를 반복하고 AJAX가 각 링크 페이지의 내용을 처리하고 해당 페이지에 지정된 내용이 있으면 다시보고하고자합니다.

내가 겪고있는 문제는 [i] linkList를 통해 반복하는 데 사용되는 값은 항상 6이며 결코 없어야한다는 것입니다. 나는 .done이 마침내 트리거 할 때 AJAX가 처음 트리거되었을 때의 값과 .done이 나중에 트리거 될 때 [i]의 값을 알 수 없도록 일부 데이터를 전달해야한다고 가정합니다.

어떻게 AJAX를 처음 호출 할 때 .done의 가치를 알 수 있습니까?

+1

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures#Creating_closures_in_loops.3A_A_common_mistake –

+0

'링크 것입니다 List'는 jQuery 객체 또는 배열입니까? –

+0

솔루션은 http://jsfiddle.net/arunpjohny/2Da7Z/1/ –

답변

35

가장 쉬운 방법은 클로저를 사용하는 것입니다. 루프에서 비동기식 무언가가있을 때마다 똑같은 일이 일어납니다. 이 슈도 코드에서

for (var i .....) { 
    async(function() { 
    use(i); 
    } 
} 

은 내부 기능 i 의해 참조 저장 위치 캡처. 루프가 실행되고 i이 최종 값으로 증가하고 비동기 콜백이 호출되기 시작합니다. 모두 동일한 위치 (값이 아님)을 찾습니다. 자동 실행 기능에 루프의 전체 내용을 바꿈

for (var i .....) { 
    (function (i) { 
    async(function() { 
     use(i); 
    }); 
    })(i); 
} 

즉 :

일반적인 해결책이있다.

여기서 이 외부 i 인 경우 랩핑 자체 실행 익명 함수로 전달됩니다. 이 고유 값의 위치는 비동기 콜백에 의해 캡처됩니다. 이런 방식으로 각 비동기는 자체 실행 기능이 호출 된 순간에 결정된 자체 값을 가져옵니다.

+4

과 같은 형태 일 수 있습니다. (function (i) {CODE}) (i); 래퍼가 완벽하게 작동하면 코드가 의도 한 결과와 함께 실행됩니다. 고맙습니다! – Edge

+5

그래서 그게 폐쇄의 요점입니다 – LazerSharks

+0

당신은 내 생명을 구했어. – krummens

11

질문의 주석 섹션에있는 링크는 코드에서 무엇이 잘못되었는지 알려주지 만 한 번 설명 된 것보다 나은 해결책을 제시 할 수 있습니다.

전달 된 콜백 각 반복

$.each(linkList, function (i, item) { 
    $.ajax({ 
     url: item.getAttribute("href"), 
     cache: false 
    }).done(function (html) { 
     var hasAppended = false; 
     if (html.indexOf('someStringOnGottenPage') != -1 && !hasAppended) { 
      hasAppended = true; 
      var id = item.getAttribute("href").substring(item.getAttribute("href").indexOf('=')); 
      $("#links a[href*='" + id + "']").append(' THIS PAGE CONTAINS SPECIFIED DATA'); 
     } 
    }); 
}) 

위한 별도의 고정을 만들 수 있도록 한 후 사용 그것이 jQuery를 오브젝트 인 경우, (이 배열 인 가정)에서 반복하는 $.each() 사용해 .each()

linkList.each(function (i, item) { 
    var $item = $(item), 
     href = $item.attr("href"); 
    $.ajax({ 
     url: href, 
     cache: false 
    }).done(function (html) { 
     var hasAppended = false; 
     if (html.indexOf('someStringOnGottenPage') != -1 && !hasAppended) { 
      hasAppended = true; 
      var id = href.substring(href.indexOf('=')); 
      $("#links a[href*='" + id + "']").append(' THIS PAGE CONTAINS SPECIFIED DATA'); 
     } 
    }); 
}) 
관련 문제