如果启动后 Internet 可用,如何使用预加载器加载外部 javascript?

How to use a preloader to load an external javascript if Internet becomes available after startup?

我一直在为我的 html5 应用程序试验 responsive voice。除了响应式语音,我的应用程序可以独立运行,不需要互联网,因为我工作的学校的互联网连接不可靠。

我之前在等待 RV javascript 加载慢速连接时遇到问题,我使用预加载器 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 秒后自动超时。可以更改超时,但我想要的是,实际上,根本没有超时!

例如,如果学生在 07:30 a.m 开始使用我的应用程序。当学校的卫星天线勉强工作时,然后在 3 p.m。乌云密布使 RV 可行,如果脚本最终加载、触发回调并且 RV 开始运行,那就太好了。

所以我有 3 个问题:

  1. 原则上,有什么理由不应该将 yepnope 超时从 10 秒更改为 12 小时?例如

    yepnope.errorTimeout = 43200000;
    
  2. 我注意到 yepnope 已被弃用。任何人都可以推荐一个没有超时选项的类似易于使用的预加载器吗?

  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
        }
      }
    });
    

一如既往地感谢您的建议。

编辑: @Steyn van Esveld 提出了一个非常好的观点:"Is there any reason you can't download the responsivevoice.js and load it locally?"

事实上,RV 脚本本身并不提供文本到语音的声音 - 它更像是一个促进者。如果你的浏览器有原生的 t-t-s 支持,它将使用它,如果没有,他们会生成音频文件(大概来自他们的网站)并将它们发送到你的浏览器。此外,如果您处于离线状态,甚至 Chrome 的原生 t-t-s 支持也会消失。例如如果你 运行:

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

离线时从控制台,returns“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);

RV api 中有一个 onerror 回调,但它的文档很模糊,我当然无法像使用此脚本那样自己控制超时。

经过更多的研究和试验,我找到了一个可行的解决方案。如果有人能想出更有效的方法,我会很高兴。首先是代码(解释如下):

    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 每分钟调用一次。我还立即调用它一次,这样如果在初始化时有可用的 Internet 连接,RV 功能就会出现。

虽然这看起来很笨重,但到目前为止效果很好。我用我经常遇到的三种情况测试了一下:

  1. 启动时完全没有网络连接;一段时间后计算机连接到网络。
  2. 启动时有本地网络连接但没有互联网连接;本地网络稍后连接到 Internet。
  3. 启动期间互联网连接速度非常慢;连接在一段时间后变得可行。

setInterval 对程序执行没有明显影响,添加的功能非常透明。如果我将计算机连接到网络并开始收听 activity,大约 1 分钟后 RV 语音将添加到我的 off-line 录音中。

我怀疑是否还有其他许多人面临类似的问题(我当然不希望任何人遇到类似问题),但如果是这样,我希望这会有所帮助。