Как использовать предварительный загрузчик для загрузки внешнего javascript, если Интернет становится доступным после запуска?

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

Ранее у меня была проблема с ожиданием загрузки javascript RV на медленном соединении, которую я решил с помощью preloader yepnope:

yepnope({
    load: 'https://code.responsivevoice.org/responsivevoice.js',
    callback: function (url, result, key) {
        if (typeof responsiveVoice!="undefined"){
                //code to activate RV functionality here
        }
    }
});

Во время тестирования я понял потенциал чего-то гораздо лучшего: yepnope автоматически отключается через 10 секунд, если скрипт не загружается и в любом случае запускает функцию обратного вызова. Этот тайм-аут может быть изменен, но я бы хотел, чтобы время ожидания вообще не было!

Например, если ученики начнут использовать мое приложение в 7:30 утра, когда школьная спутниковая антенна почти не будет работать, то в 3 часа дня облака очистятся, чтобы сделать RV жизнеспособным, было бы неплохо, если бы скрипт наконец загрузился, вызвал обратный вызов и RV вскочил в жизнь.

Итак, у меня есть 3 вопроса:

  1. В принципе, есть ли причина, по которой я не должен менять время ожидания yepnope с 10 секунд до 12 часов? например

    yepnope.errorTimeout = 43200000;
    
  2. Я заметил, что yepnope устарела. Кто-нибудь может порекомендовать такой же простой в использовании preloader без опции тайм-аута?

  3. Будет ли легче на системных ресурсах использовать setInterval? например

    var net_check = window.setInterval(yepnope, 18000); // try loading the script every 5 minutes
    

    затем, если загружается RV, отмените setInterval:

    yepnope({
      load: 'https://code.responsivevoice.org/responsivevoice.js',
        callback: function (url, result, key) {
        if (typeof responsiveVoice!="undefined"){
            clearInterval(net_check);
            //code to activate RV functionality here
        }
      }
    });
    

Спасибо как всегда за любой совет.

Редактировать: @ Стейн ван Эсвельд поднял действительно хороший вопрос: "Есть ли какая-то причина, по которой вы не можете скачать responseivevoice.js и загрузить его локально?"

На самом деле сценарий RV сам по себе не обеспечивает голоса преобразования текста в речь - это скорее посредник. Если ваш браузер имеет встроенную поддержку tts, он будет использовать его, если нет, они генерируют аудиофайлы (предположительно с их веб-сайта) и отправляют их в ваш браузер. Кроме того, даже встроенная поддержка Chrome tts испаряется, если вы не в сети. например, если вы запускаете:

voices = window.speechSynthesis.getVoices();
voices.length

в автономном режиме с консоли возвращает "0".

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

var rvStarted=false;
responsiveVoice.speak(vocEx, {onstart:function(){rvStarted=true;}}); 
setTimeout(function(){
  if (rvStarted==false){
    responsiveVoice.cancel();
    audVoc.play(); //plays a backup off-line recording 
  }
},1000);

В API RV есть обратный вызов ошибки, но он смутно задокументирован, и я, конечно, не могу самостоятельно контролировать время ожидания, используя этот скрипт.

1 ответ

Решение

После дополнительных исследований и экспериментов у меня есть решение, которое работает. Если кто-нибудь может придумать что-то более эффективное, я был бы рад. Сначала код (пояснение следует):

    function loadRV() {
    console.log("Trying to load RV");
    inject.js('https://code.responsivevoice.org/responsivevoice.js',           
        function() {
            if (typeof responsiveVoice!="undefined"){
                clearInterval(net_check);
                console.log("RV loaded");
                // code here to turn on RV functionality
            }
            else {
                console.log("RV load failed");
            }
        });
    }

    var net_check=setInterval(function(){
        loadRV();
    },60000);
    loadRV();

Теперь объяснение:

  1. Я понял, что yepnope обнаружил, что во время первой попытки не было сетевого подключения, и после этого не делал попыток загрузить javascript, несмотря на то, что сеть была включена. Проблема была не в тайм-ауте (таким образом, изменение названия вопроса.
  2. Поэтому я искал замену yepnope, которая будет пытаться загружать javascript каждый раз, когда он вызывается, независимо от того, что ранее произошло. Я в итоге наткнулся на inject.js. Это основано на yepnope с некоторыми удаленными функциями и некоторыми добавленными. Я предполагаю, что возможность проверить, есть ли сетевое соединение, была удалена, что соответствовало моим потребностям.
  3. Затем я обернул inject.js в функцию и вызывал ее каждую минуту с помощью setInterval. Я также сразу называю это один раз, чтобы функциональность RV присутствовала при наличии жизнеспособного подключения к Интернету при инициализации.

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

  1. Нет сетевого подключения вообще во время запуска; компьютер подключается к сети через некоторое время.
  2. Подключение к локальной сети, но нет подключения к Интернету во время запуска; Локальная сеть подключается к Интернету через некоторое время.
  3. Очень медленное интернет-соединение при запуске; соединение становится жизнеспособным через некоторое время.

SetInterval не оказывает заметного влияния на выполнение программы, а добавленная функциональность довольно прозрачна. Если я подключу компьютер к сети и начну прослушивание, примерно через 1 минуту голоса RV будут добавлены в мои записи в автономном режиме.

Я сомневаюсь, что многие другие сталкиваются с подобными проблемами (я, конечно, не желал бы их никому), но если это так, я надеюсь, что это поможет.

Другие вопросы по тегам