2010-02-03 2 views
5

현재 동기가 필요한 Ajax 호출이 있습니다. 그러나이 Ajax 호출이 실행되는 동안 호출이 반환 될 때까지 브라우저 인터페이스가 멈 춥니 다. 시간 초과가 발생하면 브라우저가 동결되어 significant period of time이됩니다.자바 스크립트 루프에있는 동안 브라우저 창을 업데이트 할 수 있습니까?

브라우저 (모든 브라우저)가 사용자 인터페이스를 새로 고칠 수 있지만 자바 스크립트를 실행하지 못하게 할 방법이 있습니까? 이상적으로는 window.update()과 같은 명령을 사용하면 사용자 인터페이스 스레드를 새로 고칠 수 있습니다. 이 가능할 것이다 경우

, 그때는 같은과 동기 AJAX 호출을 대체 할 수 :

obj = do_async_ajax_call(); 
while (!obj.hasReturned()) { 
    window.update(); 
} 
// synchronous call can resume 

내가 setTimeout를 사용하거나 콜백 기능을 다시 시작할 수 없습니다 이유 그입니다 (모두가 서로에 따라 너무 많은 상태 변수가, 그리고 long_function() 흐름 그렇지 않으면 어떻게 든 재개 할 것) : 실행 흐름이 중단 될 수 없다

function long_function() { 
    // lots of code, reads/writes variable 'a', 'b', ... 
    if (sync_call_is_true()) { 
    // lots of code, reads/writes variable 'a', 'b', ... 
    } else { 
    // lots of code, reads/writes variable 'a', 'b', ... 
    } 
    // lots of code, reads/writes variable 'a', 'b', ... 
    return calculated_value; 
} 
+2

왜 호출이 동기되어야합니까? –

+1

전체 전화 코드를 게시 할 수 있습니까? 이것은 아마도 단순화 될 수 있으며 XHR 함수를 사용하여 필요한 것을 지원할 수 있습니다 (jQuery가 옵션이 아니라면 더 깨끗합니다). 어느 쪽도 옵션이 아니면 함수의 이름을'do_sync_jax_call(); '로 바꾼다. –

답변

3

을 콜백에서 중복 될 수있다 비동기 요청을 처리하고 콜백을 사용합니다. 아주 간략 예는 다음과 같습니다

obj = do_async_ajax_call(function (data, success) 
{ 
    if (success) 
    { 
     // continue... 
    } 
}); 

function do_async_ajax_call(callback) 
{ 
    var xhr = new XMLHttpRequest(); 
    xhr.open("GET", "http://mysite.com", true); 
    xhr.onreadystatechange = function() 
    { 
     if (xhr.readyState == 4 && xhr.status == 200) 
      callback(xhr.responseXML, true); 
     else if (xhr.readyState == 4) 
      callback(null, false); 
    } 
    xhr.send(); 
} 

당신은 아약스 요청 함수에 매개 변수로 익명 함수를 전달하는이 방법. ajax가 완료되면 전달 된 함수가 responseXML이 전달되면서 호출됩니다. 그동안 브라우저는 호출이 완료 될 때까지는 일반적으로 자유롭게 수행했습니다. 여기에서 나머지 코드는 계속됩니다.

+0

일반적으로 충분 하겠지만, 질문에 업데이트 된대로 동작 흐름을 나눌 수 없다. 나는 지금 다른 접근법을 시도하고있다 ... – jevon

+0

그것은 항상 * 분할 가능하다. 이것은 CPS 변환입니다 ("연속 전달 스타일"조회, 연속 매개 변수는 콜백입니다). 로컬 상태 변수는 콜백 함수에서 단순히 닫혀 있습니다. 루프는 재귀 호출이됩니다. 일단 당신이 그것의 걸림 새를 얻으면 그것은 열심히 또는 애매하지 않다. –

+0

나는 항상 가능하다고 동의하지만,이 경우 가장 좋은 솔루션은 아니었다. (너무 많은 상태 변수가있다!) :) 결국, 이전 콜백 (또는 일반 서버 폴링) 결과를 사용하여 클라이언트를 업데이트했다. 필요한 경우 동기 호출의 캐시 된 값으로 처리하므로 Ajax를 전혀 호출 할 필요가 없습니다. – jevon

0

통화의 나머지를 가지고 넣어 콜백에서 결과가 돌아올 때 호출됩니다. 나는 이것이 당신이하는 것이 완전히 불가능하다는 것을 진지하게 의심합니다. 당신이 전화에 넣어해야하는 논리는

0

비동기 아약스의 setTimeout 다음 가져오고 당신은 당신의 동기 요청을 교체해야합니다 (콜백에 의해 트리거) 덩어리에서 처리 작업

0

자바 스크립트는 단일 스레드입니다. 따라서 정의에 따라 조수가 진행되는 동안 UI를 업데이트 할 수 없습니다. 그러나 파이어 폭스 3.5부터는 웹 작업자라고 불리는 멀티 스레드 자바 스크립트에 대한 지원이 추가되었습니다. 웹 작업자는 페이지 UI에 영향을 줄 수는 없지만 UI 업데이트를 차단하지는 않습니다. 우리 직원은 Chrome과 Safari에서도 지원됩니다.
AJAX 호출을 백그라운드 스레드로 옮기고 실행이 완료 될 때까지 기다리더라도 사용자는 UI에서 버튼을 누르고 값을 변경할 수 있습니다 (그리고 내가 이해할 수있는 한, 그것이 사용자의 것입니다. 피하려고). 사용자의 변경을 막기 위해 제안 할 수있는 유일한 방법은 전체 UI를 차단하고 웹 호출이 반환 될 때까지 페이지와의 상호 작용을 허용하지 않는 회 전자입니다.

+0

사용자가 페이지와 상호 작용하고 상호 작용이 대기 중인지 신경 쓰지 않아도됩니다. 하지만 현재 Firefox에서 동기식 Ajax 호출이 실행되는 동안 브라우저 전체가 정지합니다. 이것이 내가 막고 싶은 것입니다. – jevon

관련 문제