Как внедрить скрипт только один раз, используя GWT ScriptInjector?

У меня есть JavaScript, который я хочу внедрить в DOM при загрузке определенного компонента, использующего этот скрипт. Компонент существует в нескольких местах в моем приложении, поэтому для пользователя разумно загружать этот компонент несколько раз за сеанс. Есть ли способ предотвратить загрузку ScriptInjector одного и того же сценария несколько раз?

Важный вопрос производительности: если я уже загрузил скрипт, вызовет ли вызов inject() того же скрипта браузер, чтобы загрузить его во второй раз, или он поймет, что у него уже есть скрипт?

Я знаю, что я мог бы создать некоторую глобальную переменную, например FANCY_JS_SCRIPT_LOADED = false;, а затем в onSuccess обратного вызова вызвать что-то вроде FANCY_JS_SCRIPT_LOADED = true;, но это кажется очень, очень... неуклюжим.

Документы: http://www.gwtproject.org/javadoc/latest/com/google/gwt/core/client/ScriptInjector.html


person Glen Pierce    schedule 31.08.2017    source источник


Ответы (1)


Что ж, если у вас нет такой «жесткой» линии, ScriptInjector сама должна.

Другие варианты — сохранить список всех загруженных файлов JS — и никогда не удалять их теги <script>. Также никогда не загружайте случайно одно и то же из другого домена, другого протокола, другой версии в другую часть вашего кода...

Но ScriptInjector должно быть достаточно для внедрения любого скрипта, либо из строки, либо из URL-адреса. Если вы планируете какое-то повторное использование подобного инструмента, вы сами его обертываете.


Еще одна мысль: поместите вызов ScriptInjector в блок инициализатора класса в классе, который в нем нуждается — GWT безопасно скомпилирует его, чтобы он запускался только один раз, независимо от того, сколько экземпляров этого класса создано. Однако это затруднит настройку обратного вызова, в зависимости от того, как вы используете файл JS.

Однако в этом случае вам действительно нужно что-то нестандартное - что-то вроде (в почти правильном псевдокоде, который я не запускал):

private static boolean fancyJsLoaded = false;
public static void loadFancyScript(Callback<Void, Exception> callback) {
  if (fancyJsLoaded) {
     callback.onSuccess();
  } else {
    fancyJsLoaded = true;
    ScriptInjector.fromUrl("path/to/file.js").setCallback(callback);
  }
}
person Colin Alworth    schedule 01.09.2017