Как я могу контролировать порядок выполнения Javascript?

У меня возникают проблемы с параллелизмом с веб-страницей, которую я создаю. В принципе, у меня есть три файла сценариев, которые я использую для хранения некоторых данных:

script1.js:

var myValue = 1; 

script2.js:

 var myValue = 2; 

script3.js:

 var myValue = 3; 

И у меня есть одна страница, mypage.html, которая в основном выглядит так:

   function get_number() { var script_file = GetQueryStringValue( "run" ); e = document.createElement('script'); e.type='text/javascript'; e.src = script_file + ".js" head.appendChild( e ); document.write( myValue ); }   
Click me!

Основная идея этой страницы заключается в том, что вы будете запрашивать ее следующим образом: mypage.html?run=script1 который будет get_number() функции get_number() для динамической вставки script1.js в script1.js . Затем я вызываю get_number() чтобы отобразить значение, загруженное из скрипта.

Теперь я урезал выше, что, на мой взгляд, является релевантными частями, и я, конечно, забыл кучу вещей. Мой фактический код загружает большой массив значений и интереснее … Но я надеюсь, что кто-то может мне помочь в этом.

Я обнаружил, что в IE число отображается правильно.

В Firefox, Chrome и Safari я получаю сообщение об ошибке, которое myValue не определено. Однако, если я нажму на « Click me который я создал, номер отобразится правильно. Итак, я знаю, что правильно загружаю внешний файл javascript. Но он просто не загружен вовремя, чтобы моя get_number() работала правильно.

Теперь я немного взломал файл, чтобы функция get_number выглядела так:

  function get_number() { var script_file = GetQueryStringValue( "run" ); e = document.createElement('script'); e.type='text/javascript'; e.src = script_file + ".js" head.appendChild( e ); setTimeout( function() { document.write( myValue ), 10 } ); } 

Задержка setTimeout достаточно для обновления DOM и загрузки JavaScript в большинстве случаев. Но это общий взлом. Firefox обычно загружает этот «улучшенный» код все время, в то время как Chrome и Safari удается получить значение около 50% времени.

Итак, я думаю, мне интересно, есть ли лучший способ выполнить то, что я пытаюсь сделать здесь? Очень важно, чтобы значение выводилось извне (по строке запроса), но, кроме этого, я очень гибкий.

Не могли бы вы добавить вызов функции в ваши файлы сценариев, чтобы при запуске они вызывали функцию, которая выполняет вашу

 document.write( myValue ); 

Так что script1.js будет

 var myValue = 1; scriptLoaded(); 

и ваш основной файл будет иметь:

 function scriptLoaded(){ document.write( myValue ); } 

Этот метод динамической загрузки файлов сценариев с использованием DOM-методов, таких как head.appendChild, является асинхронным, что означает, что страница не дожидается загрузки до запуска какого-либо дополнительного кода. Если вы не хотели этого асинхронного поведения, вы могли бы загружать их с помощью обычных элементов в свой HTML, или вы могли бы объединиться с «синхронным» XMLHttpRequest, чтобы захватить его и eval (), чтобы запустить его.

Вы, вероятно, не хотите этого делать, хотя, поскольку асинхронность делает загрузку всей страницы быстрее, так или иначе. Вероятно, вам просто нужно добавить логику, ожидающую загрузки динамически загружаемого скрипта, прежде чем продолжить следующий бит кода. Это может, однако, включать опрос с использованием setInterval (), пока вы не заметите, что переменная из включенного сценария определена. Или вы можете добавить код в включенный скрипт, который вызывает метод для того, что его ждало.

Или вы можете посмотреть, как jQuery делает что-то подобное, ищите, где определен метод ajax, в частности эти части …

 var script = document.createElement("script"); // then later ... script.onload = script.onreadystatechange = function(){ if ( !done && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete") ) { // do processing head.removeChild( script ); } }; // ... head.appendChild(script);