2009-05-24 2 views
1

У меня уже есть код, который ленив загружает скрипты по запросу. Моя проблема теперь ждет выполнения определенного кода, пока объект не станет доступен. Я не могу использовать setTimeout(), потому что он не блокирует выполнение.Ожидание на ленивых Загруженных объектах без блокировки?

Так что же это хороший способ «подождать» для загрузки без блокировки браузера?

Опять же, нельзя использовать raw setTimeout().

ответ

3

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

var loadingScripts = 0; 
var loadScript = function() { 
    // Do what you need to do to load the script... 

    loadingScripts++; 
} 

var loadedScript = function() { 
    loadingScripts--; 
    if (loadingScripts == 0) { 
     // Kick off execution of code that requires the lazy loaded scripts. 
    } 
} 

Затем в сценарии, вы бы добавить этот код на дно:

loadedScript(); 

Вы можете оживить этот пример с массив вместо целого (для отслеживания загрузки определенных скриптов). Вы также можете использовать объект, чтобы связать конкретные вызовы функций с завершением определенных сценариев. Я оставил свой пример простым, но спросите, хотите ли вы, чтобы я показал, как это сделать, расширьте код.


Вот как вы можете использовать функцию обратного вызова, чтобы продолжить выполнение определенного кода при загрузке сценария (опять же, если вы контролировать сами скрипты).

var scriptCallbacks = {} 
var loadScript = function(scriptname, callback) { 
    // Do what you need to load scriptname 

    scriptCallbacks[scriptname] = callback; 
} 

var loadedScript = function(scriptname) { 
    (scriptCallbacks[scriptname])(); 
} 

Затем, когда вы хотите загрузить сценарий, вы делаете что-то вроде этого ...

var callback = function() { 
    // Write exactly what you want executed once your script is loaded 
} 

loadScript("MyScript.js", callback); 

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

loadedScript("MyScript.js"); 
+0

Загруженный скрипт используется не только для одного или двух вещей. Это полные библиотеки, которые вызываются из разных разделов сайта по мере необходимости. Нет чистого пути (я могу думать), чтобы узнать, какой источник запросил загрузку. – Spot

+0

Возможно создание функции lazyloading, которая выполняет другую функцию в качестве обратного вызова и запускает обратный вызов при загрузке сценария. Основная часть моего примера состоит в том, что вы можете связать связанный скрипт, когда он загружен, а не пытаться опросить его. –

+0

Однако он полностью уничтожает возможность использования этого встроенного. Спасибо за информацию. – Spot

2

Я бы сделал это иначе, чем упоминал Даниил. Все элементы запускают событие загрузки при загрузке, а файл Javascript загружается после того, как он оценил содержимое. Таким образом, вы можете установить обработчик событий, чтобы продолжить выполнение после их наличии:

var loadScript = function(fileName, callback) { 
    var head = document.getElementsByTagName('head')[0]; 
    var script = document.createElement('script'); 
    script.type = 'text/javascript'; 
    script.src = fileName; 

    script.onload = callback; 
    script.onreadystatechange = function() { 
     if(this.readyState == 'complete') { 
      callback(); 
     } 
    }; 
    head.appendChild(script); 
}; 

И пример использования:

var bar = function() { 
    Foo.baz(); 
}; 
if(!window.Foo) { 
    loadScript('Foo.js',bar); 
} else { 
    bar(); 
} 
+0

Важно отметить, что script.onload не работает в некоторых браузерах (например, Internet Explorer). –

+0

Однако в IE он запускает событие onreadystatechange, поэтому я мог бы написать это лучше для использования onload или onreadystatechange, чтобы сделать его crossbrowser – seanmonstar

Смежные вопросы