Как использовать предварительный загрузчик для загрузки внешнего 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 вопроса:
В принципе, есть ли причина, по которой я не должен менять время ожидания yepnope с 10 секунд до 12 часов? например
yepnope.errorTimeout = 43200000;
Я заметил, что yepnope устарела. Кто-нибудь может порекомендовать такой же простой в использовании preloader без опции тайм-аута?
Будет ли легче на системных ресурсах использовать 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();
Теперь объяснение:
- Я понял, что yepnope обнаружил, что во время первой попытки не было сетевого подключения, и после этого не делал попыток загрузить javascript, несмотря на то, что сеть была включена. Проблема была не в тайм-ауте (таким образом, изменение названия вопроса.
- Поэтому я искал замену yepnope, которая будет пытаться загружать javascript каждый раз, когда он вызывается, независимо от того, что ранее произошло. Я в итоге наткнулся на inject.js. Это основано на yepnope с некоторыми удаленными функциями и некоторыми добавленными. Я предполагаю, что возможность проверить, есть ли сетевое соединение, была удалена, что соответствовало моим потребностям.
- Затем я обернул inject.js в функцию и вызывал ее каждую минуту с помощью setInterval. Я также сразу называю это один раз, чтобы функциональность RV присутствовала при наличии жизнеспособного подключения к Интернету при инициализации.
Хотя это кажется громоздким, до сих пор это работает очень хорошо. Я проверил это с тремя ситуациями, с которыми я обычно сталкиваюсь:
- Нет сетевого подключения вообще во время запуска; компьютер подключается к сети через некоторое время.
- Подключение к локальной сети, но нет подключения к Интернету во время запуска; Локальная сеть подключается к Интернету через некоторое время.
- Очень медленное интернет-соединение при запуске; соединение становится жизнеспособным через некоторое время.
SetInterval не оказывает заметного влияния на выполнение программы, а добавленная функциональность довольно прозрачна. Если я подключу компьютер к сети и начну прослушивание, примерно через 1 минуту голоса RV будут добавлены в мои записи в автономном режиме.
Я сомневаюсь, что многие другие сталкиваются с подобными проблемами (я, конечно, не желал бы их никому), но если это так, я надеюсь, что это поможет.