2011-12-21 5 views
3

나는 데이터를 얻기 위해 getPropertyId 함수로 아약스를 호출한다. 콜백을 사용하여 결과를 얻은 다음 사용합니다. 내 문제는 두 번째 각 루프가 함수 안에 넣을지라도 첫 번째 루프가 끝나기 전에 시작된다는 것입니다. 첫 번째 코드가 끝난 후 두 번째 루프를 시작하기 위해 코드를 동기화 할 수 있습니까? 감사동기화 코드

Plugins.DataHelper.getPropertyId(PropertyID, function(data){ 
    //code using data retrived with getPropertyId function 

    $.each(list, function(index,value){ 
    //code "A" containing asynchronous calls 
    }); 
}); 

$.each(filtredList, function(index,value){ 
    //code "B" 
}); 
+0

은 왜 포장하지 코드 B는 함수의 각 루프를 호출하고 코드 A의 루프를 호출합니다. –

+1

내가 알고있는 유일한 [$ .each()] (http://api.jquery.com/jQuery.each/)는 동기식입니다. 두 번째 호출을'$ .each()'에 첫 번째 호출과 동일한 함수로 두는 것이 여전히 비동기 동작을 일으키는 것은 확실합니까? –

+0

작동하지 않았다. 코드 A를 끝내기 전에 호출을 만든다. – Djoz

답변

1

이것은 JavaScript의 특성이므로 나중에 비슷한 문제가 발생하지 않도록 이벤트 기반 프로그래밍에 익숙해 져야합니다.

는 기본적으로 그 같은 작업을해야합니다 :

Plugins.DataHelper.getPropertyId(PropertyID, function(data){ 
    //code using data retrived with getPropertyId function 

    $.each(list, function(index,value){ 
     //code "A" 
    }); 
    $.each(filtredList, function(index,value){ 
     //code "B" 
    }); 
}); 

당신이 AJAX는 "코드 A"내부 호출하고 있습니다 그러하지 아니하다. 이 경우 운이 없으므로 동기 호출 (일반적으로 나쁜 생각)을 사용하거나 이벤트를 기반으로 작업하도록 코드를 다시 작성하도록 "코드 A"를 변경해야합니다.

하나의 아이디어는 처리 할 요소의 수를 결정한 다음 각 항목이 처리 된 후 콜백을 호출하는 것입니다. 이 콜백은 모든 항목이 처리되었는지 확인해야합니다 (카운터를 증가시키고 처리 할 항목 수와 비교).이 메커니즘은 잠금이 작동하는 것과 유사합니다. 함수가 모든 항목을 처리했다고 판단하면 일부 작업을 수행합니다 (그렇지 않은 경우).

+0

사실 저는 Ajax를 "코드 A"라고 부릅니다.이 코드는 각 루프 내부에 있어야하기 때문에 코드를 정렬하거나 두 번째 루프에서 첫 번째 루프를 기다리게 할 수 있습니까? 이미 이벤트로 작업하지만 두 번째 루프가 포함될 이벤트를 어디에서 제기 할 수 있습니까? – Djoz

+1

@YoussefMAKNI : 함수 내에서 두 번째 루프를 푸시하고 저장하십시오 (지금 실행하지 마십시오!). 이 함수는 앞서 언급 한 잠금 값을 확인해야합니다. 그런 다음, 각 AJAX 요청을 비동기 적으로 처리 한 후에는 성공 핸들러 내에서 잠금 값을 변경 한 다음 콜백을 호출해야합니다 (성공 핸들러에서 계속). 콜백은 잠금 값을 검사하고 결국 잠금을 기반으로 모든 요청이 처리되었음을 결정한 후 루프를 실행합니다. 알았다? – Tadeck

+0

예, 작동합니다. Tadeck 감사합니다! – Djoz

1

당신은 정말 syncronised (= 차단) 요청을 만들 수 있지만, 그것은 아주 나쁜 브라우저 동작입니다. 콜백 함수가 작동하도록하는 것이 훨씬 낫습니다. 따라서 첫 번째 Ajax 호출이 완료되면 (성공/오류) 코드를 "계속"해야합니다.

Plugins.DataHelper.getPropertyId(PropertyID, function(data){ 
    XHRobject.onreadystatechange = function() { 
     if(XHRobject.readyState === 4) { 
      $.each(list, function(index,value){ 
       //code "A" 
      }); 
     } 
    } 
}); 

주, 그 원리를 설명하는 간략화 된 예이다. jQuery에 태그를 추가 했으므로 promise 객체를 호출하여 매우 georgous하게 만들 수 있습니다. 보이는 모양

Plugins.DataHelper.getPropertyId(PropertyID, function(data){ 
    $.ajax({}).done(function() { 
     $.each(list, function(index,value){ 
      //code "A" 
     }); 
    }); 
}); 
0

첫 번째 부분은 ajax 호출이 완료 될 때까지 대기합니다.

그 동안 스크립트는 계속 진행되고 두 번째 스크립트가 계속 수행됩니다.

첫 번째 각 루프 바로 다음에 두 번째를 넣으려고했습니다.

0

당신은 기존의 Lock 의미

Plugins.DataHelper.lock = false;//release 
Plugins.DataHelper.getPropertyId(PropertyID, function(data){ 
    //code using data retrived with getPropertyId function 

    $.each(list, function(index,value){ 
     Plugins.DataHelper.lock = true;//acquire 
     //code "A" 
     Plugins.DataHelper.lock = false;//release 
    }); 
}); 
while(Plugins.DataHelper.lock) 
    continue;//wait until released 
$.each(filtredList, function(index,value){ 
    //code "B" 
}); 

을 사용할 수 있습니다 또는 당신은 당신의 아약스 XHR의 마무리 콜백 후 호출하는 다음 기능을 추가 할 수 있습니다.

var nextF = function(){}; 
Plugins.DataHelper.getPropertyId(PropertyID, function(data){ 
    //code using data retrived with getPropertyId function 

    $.each(list, function(index,value){ 
     //code "A" 
     nextF(); 
    }); 
}); 
nextF = function(){ 
$.each(filtredList, function(index,value){ 
    //code "B" 
}); 
}//You need to pass the scope to the nextF function like nextF.call(scope) where scope is cached somewhere 
+0

테스트 해 보셨습니까? 결과가 나올 때까지 기다리지 않고 브라우저를 멈추거나 "코드 B"를 즉시 실행하는 것은 좋지 않습니다. – Tadeck

+0

예. 아약스 호출이 잠금을 해제하지 않는 한, 첫 번째 코드는 고정됩니다. 그리고 나는 그들 중 누구도 시험하지 않았다. 두 번째는 얼지 않는다. –

1

당신과 같이 콜백 함수 내에서 '각'호출 두 번째를 이동하여이를 달성 할 수 있어야한다 :

Plugins.DataHelper.getPropertyId(PropertyID, function(data){ 
    //code using data retrived with getPropertyId function 

    $.each(list, function(index,value){ 
    //code "A" 
    }); 

    $.each(filtredList, function(index,value){ 
    //code "B" 
    }); 
}); 

편집 : 자세한 내용은이 문서 체크 아웃 : flow control in javascript

+0

"코드 A"안에 AJAX 호출이 있기 때문에 작동하지 않습니다 – Djoz

+0

'코드 A'가 필터링 된 목록을 작성하기 위해 아약스 호출을하면 각 블록을 하나의 블록으로 병합하고 '코드 B'를 수행 할 수 있습니다. 성공 처리기. – Darren

관련 문제