2016-07-16 4 views
1

В моем случае, я использую как внешний, так и встроенный контент javascript. У меня есть следующая структура.Как задержать время загрузки встроенного javascript?

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

home.html включает в себя header.html и footer.html. header.html файл содержит config-load.js.

config-load.js делает вызов ajax для получения конфигураций, основанных на стадии, от холангового бэкэнда. Это может занять несколько миллисекунд.

Есть несколько встроенных скриптов в home.html, который использует конфиги, собранные config-load.js ajax call.

So config-load.js вызов ajax должен быть выполнен до загрузки встроенных скриптов. Но это происходит по-другому.

Я пытался использовать время цикла оттянуть время загрузки для встроенных скриптов, как показано ниже,

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

Но это блокирует поток. Страница застревает в цикле while. Есть ли другой способ достичь этого?

EDIT 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

Попробуйте поместить 'config-load.js' и' anotherscript.js' в свой 'footer.html' –

ответ

1

Помните, что javascript является асинхронным и у вас нет полного контроля над последовательностями загрузки скриптов, если вы не используете новую функцию javascript или promises. Но в вашем случае на самом деле это не нужно.

Первое, что вам нужно сделать, это включить в голову раздел 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> 

EDIT:

Есть довольно много ошибок в вашем подходе. Прежде всего, нет необходимости вызывать запросы ajax в двух отдельных сценариях. Используя вышеупомянутую методику обещания, вы можете связать ответы. Вот краткий пример того, как JQuery обещания работают:

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); 
} 

Помните: вызов в группе цепи возвращает ответ.Это означает, что вы можете делегировать ответ на следующую цепочку, а это значит, что когда запрос будет разрешен, вы можете передать результат на следующий вызов.

Применение к вашему примеру, когда вы получаете ответ, вызвав службу конечных точек, вы можете передать результат в качестве параметра для следующего вызова, и это будет доступно только тогда, когда ответ первого вызова будет разрешен.

В качестве примера отметим это fiddle.

Применяя эту технику, необходимо больше не проверять configReceived = true;.

Еще одна вещь, которую вы должны убедиться в том, что jQuery включен, прежде чем вы пытаетесь вызвать jQuery.ajax.

Вот некоторые упоминания о обещаниях:

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 не является функцией'. У меня есть идея. – Dany

+0

Я боюсь, что jquery не загружен, поэтому вы получаете эту ошибку. –

+0

Да. Когда я удаляю window.onload, я не вижу эту ошибку, но порядок отличается. не знаю, какова связь между этими двумя. – Dany

1

«в то время как петля» является синхронным, что означает, что он будет блокировать поток и делает целое приложение застревают.

Порядок выполнения асинхронных скриптов Javascript не гарантируется, поэтому вы должны использовать «обратный вызов» или в ES6 вы можете использовать обещание, ES7 вы можете использовать async, ждать.

Во всяком случае, может быть лучше обернуть config-load.js яваскрипт кода в функции, если вы используете AJAX API JQuery, в коде может выглядеть следующим образом:

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

И в вашем инлайн Javascript может выглядеть как этот

<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> 
Смежные вопросы