2016-07-16 8 views
1

내 유스 케이스에서는 외부 및 인라인 자바 스크립트 콘텐츠를 모두 사용하고 있습니다. 나는 다음과 같은 구조를 가지고있다.인라인 자바 스크립트 로딩 시간을 지연시키는 방법은 무엇입니까?

app/ 
     header.html 
     home.html 
     config-load.js 
     footer.html 

home.htmlheader.htmlfooter.html이 포함되어 있습니다. header.html 파일에는 config-load.js이 포함됩니다.

config-load.js은 golang 백엔드에서 스테이지를 기반으로 configs를 가져 오기 위해 ajax 호출을합니다. 이것은 몇 밀리 초의 지연이있을 수 있습니다.

config-load.js ajax 호출로 수집 된 구성을 사용하는 home.html에는 인라인 스크립트가 거의 없습니다.

그래서 config-load.js 인라인 스크립트를로드하기 전에 ajax 호출을 완료해야합니다. 하지만 다른 방향으로 로딩 중입니다.

나는

while(configReceived == false) 
{ 
    setTimeout(function(){ 
    console.log("waiting for config"); 
    }, 2000); 
} 
if(configReceived) 
{ 
    //process configs 
} 

그러나이 블록 스레드, 아래와 같이 인라인 스크립트로드 시간을 지연 while 루프를 사용했습니다. 페이지가 while 루프에서 멈 춥니 다. 이것을 달성 할 다른 방법이 있습니까?

편집 1 : 여기

<script type="text/javascript"> 
    window.onload = function() { 
     time = new Date($.now()); 
     var tagsArray = ["C", "C++", "Go", "Ruby"]; 
     //var tagsArray = []; 
     requestJSON = '{"Method":"GET","AppName":"Web-app","ServiceURL":"'+endpoints.Tags.HTTPEndpoint.URL+'","Properties":null,"Object":"","Timestamp":"'+time+'"}' 
     $.ajax({ 
     type: "GET", 
     url: endpoints.Tags.HTTPEndpoint.URL, 
     data: requestJSON, 
     processData: false, 
     contentType: "application/json;", 
     dataType: "json", 
     async: false, 
     success: function(data){ 
      console.log("tags retrieved successfully info updated successfully") 
      console.log("Tags ", data.Object) 
      tagsArray = data.Object 
     }, 
     failure: function(errMsg) { 
      console.log("Error occured in getting tags ", errMsg) 
     } 
     }); 
     $("#myTags").tagit(); 
     $("#tags").tagit({ 
     fieldName: "tagsName", // The name of the hidden input field 
     availableTags: tagsArray, 
     allowSpaces:true, 
     caseSensitive:false, 
     removeConfirmation:true, 
     placeholderText:"Tags", 
     tagLimit: 5, 
     allowDuplicates: false, 
     singleField: true, // Use a hidden input element with the fieldName name 
     singleFieldDelimiter: ',', // Optional, default value is same. 
     onlyAvailableTags: false 
     }); 
    } 
</script> 

그리고 내 설정 - load.js 아래처럼 보이는, 인라인 스크립트 내용입니다

////////////////////////////////////////////////////////// 
// code block to get the service endpoints by stage starts 
var xhr = new XMLHttpRequest(); 
xhr.onreadystatechange = function() { 
    if (xhr.readyState == 4 && xhr.status == 200) { 
     endpoints = JSON.parse(xhr.responseText); 
     console.log("server endpoints be ", endpoints); 
     configReceived = true; 
    } 
} 
xhr.open("GET", "/config", true); 
try { 
    xhr.send(); 
} catch (err) { 
    // handle error 
    console.log("Error occured in getting the service endpoints. This may break all ajax services"); 
} 
// code block to get the service endpoints by stage ends 
//////////////////////////////////////////////////////// 

내가 지난 3 일 동안 노력하고 있지만, 불운.

+0

'footer.html'에'config-load.js'와'anotherscript.js'를 넣으십시오. –

답변

1

async await 새 자바 스크립트 기능 또는 promises을 사용하지 않는 한 자바 스크립트가 비동기식이며 스크립트로드 순서를 완전히 제어 할 수 없다는 점에 유의하십시오. 그러나 귀하의 경우에는 이들이 실제로 필요하지 않습니다.

먼저 DOM 섹션에 머리 부분에 config-load.js을 포함시켜야합니다. 이렇게하면 DOM을 채우기 전에 파일이로드된다는 보장이 있습니다.

또 다른 한가지는 인라인 스크립트 내에 window.onload 함수를 사용하여 브라우저가 모든 DOM 구조가 생성되어 완전히 채워진 후에 만 ​​스크립트를 구문 분석하도록하는 것입니다.

그래서 당신의 HTML 섹션 내부의 window.onload 기능 콜백으로 함수를 래핑 :

<script type="text/javascript"> 
    window.onload = function() { 
     while(configReceived == false) 
     { 
      setTimeout(function(){ 
      console.log("waiting for config"); 
      }, 2000); 
     } 
     if(configReceived) 
     { 
      //process configs 
     } 
    } 
</script> 

편집 :

당신의 접근 방식에 꽤 많은 오류가 있습니다. 무엇보다 먼저 두 개의 스크립트로 아약스 요청을 호출 할 필요가 없습니다. 위에서 언급 한 약속 기술을 사용하면 응답을 연결할 수 있습니다.

function first() { 
    return $.ajax(...); 
} 

function second(data, textStatus, jqXHR) { 
    return $.ajax(...); 
} 

function third(data, textStatus, jqXHR) { 
    return $.ajax(...); 
} 

function main() { 
    first().then(second).then(third); 
} 

기억 : 체인 그룹의 호출은 응답을 반환 여기 JQuery와 약속이 작동하는 방법에 대한 간단한 예입니다.즉, 응답을 다음 체인에 위임 할 수 있습니다. 즉, 요청이 해결되면 결과를 다음 호출로 전달할 수 있습니다.

예제에 적용하면 끝점 서비스를 호출하여 응답을받을 때 결과를 매개 변수로 전달하여 첫 번째 호출의 응답이 해결 될 때만 액세스 할 수 있습니다.

예를 들어 fiddle을 확인하십시오.

이 기술을 적용하면 더 이상 필요하지 않습니다. configReceived = true;을 확인하십시오.

jQuery.ajax를 호출하기 전에 jQuery가 포함되어 있는지 확인해야합니다. 여기

는 약속에 대한 일부 참고 문헌이다 :

http://www.danieldemmel.me/blog/2013/03/22/an-introduction-to-jquery-deferred-slash-promise/ "루프 상태"는 스레드를 차단 수단 전체 애플리케이션 붙어있게하는 동기 http://www.bitstorm.org/weblog/2012-1/Deferred_and_promise_in_jQuery.html https://davidwalsh.name/write-javascript-promises

+0

감사합니다. Simo. 나는 인라인 스크립트에서 [tag-it] (http://aehlke.github.io/tag-it/)을 사용하고 있습니다. 창로드를 할 때'Uncaught TypeError : $ (...). tagit is not function'과 같은 에러가 발생합니다. :(. 당신은 어떤 생각이있어. – Dany

+0

jquery가로드되지 않은 것 같아서이 오류가 발생합니다. –

+0

예. window.onload를 제거하면이 오류가 나타나지 않지만 순서가 다릅니다. 이 둘 사이의 관계가 무엇인지 확실하지 않습니다. – Dany

1

.

자바 스크립트 비동기 스크립트의 실행 순서가 보장되지 않으므로 "콜백"을 사용하거나 약속을 사용할 수있는 ES6에서 비동기를 사용할 수 있습니다.

어쨌든 더 나은 방법은 jQuery의 AJAX API를 사용하는 경우, 함수에 config-load.js 자바 스크립트 코드를 래핑 인 코드 할 수있다 다음과 같습니다

function loadConfigAjax(callback){ 
    $.ajax({url: "http://myconfig", success: function(config){ 
    callback(config) 
}}); 
} 

을 그리고 인라인의 자바 스크립트이

이 비슷한 외모
<script type="text/javascript"> 
    window.onload = function() { 
     var configReceived = function(config){ 
      //process configs 
     }; 
     // pass the configReceived as callback 
     // so that configReceived function will always be invoked after config received 
     loadConfigAjax(configReceived); 
    } 
</script>