jQuery的getScript()回调是不可靠的还是我做错了什么?

Oll*_*son 20 javascript jquery

我正在使用以下一些脚本来加载另一个:

$.getScript("CAGScript.js", function () {
    try {
        CAGinit();
    } catch(err) {
        console.log(err);
    }
});
Run Code Online (Sandbox Code Playgroud)

我们的想法是$ .getScript加载脚本,然后在完成后执行回调.CAGInit()是一种生活在其中的功能CAGScript.js.

问题是大约一半的时间,CAGInit()不会触发(在任何浏览器中).登录到Firebug控制台会报告它未定义.其余的时间它完美地运作.

有没有人有任何想法我做错了什么?

谢谢.

Fab*_*ice 23

我注意到FF 3.6的问题.

解决方案是同步加载脚本.

正如jQuery的文档中所提到,getScript是以下的简写:

$.ajax({
  url: url,
  dataType: 'script',
  success: success
});
Run Code Online (Sandbox Code Playgroud)

如果我使用以下代替getScript,一切正常:

$.ajax({
  url: url,
  dataType: 'script',
  success: success,
  async: false
});
Run Code Online (Sandbox Code Playgroud)

  • 我看到这篇文章已有近5年的历史,但是当我试图以这种方式加载任何脚本时它就相当于`$('body').append('<script src ="blah.js"> </ script> ');`在这两种情况下我得到这个Chrome警告:'主线程上的同步XMLHttpRequest因其对最终用户体验的不利影响而被弃用.如需更多帮助,请查看http:// xhr.spec.whatwg.org/.` (2认同)

小智 21

只想提供一些关于这个问题的见解.如果您正在加载的代码中出现错误,并且(至少在使用jQuery 1.7.1的Chrome上)错误将被吞没,则不会触发回调.我发现在我加载的代码中有一个来自自动完成的杂散花括号,并且回调函数没有触发.这里的间歇行为可能是由更改测试之间加载的代码引起的.


Jam*_*mes 10

如果文件保存在同一个域中,那么jQuery将使用XHR检索其内容,然后全局"评估"它.这应该工作正常,但如果你遇到问题,那么我建议使用注入脚本标记的替代方法.不幸的是,jQuery没有公开这个功能所以你必须自己做:

var script = jQuery('<script/>').attr('src', 'CAGSCript.js').appendTo('head');

var timer = setInterval( function(){ 
    if (window.CAGInit !== undefined) {
        clearInterval(timer);
        script.remove();
        // Do your stuff:
        CAGInit();
    }
}, 200);
Run Code Online (Sandbox Code Playgroud)

最好把它抽象成一个函数; 以上只是一个例子......

  • 请注意,此代码依赖于轮询.间隔似乎合理,在许多情况下它会正常工作,但它肯定不是理想的或通用的解决方案.以这种方式轮询意味着在代码准备好和用户获得好处之间几乎总会有明显的延迟. (3认同)

小智 9

刚刚在firefox上遇到了同样的问题,用一点点黑客解决了它.

将它应用于您的示例:

$.getScript("CAGScript.js", function (xhr) {
    try {
        CAGinit();
    } catch(err) {
        eval(xhr);
        CAGinit();
    }
});
Run Code Online (Sandbox Code Playgroud)

基本上强制评估XHR响应,如果它本身不能这样做的话.


小智 4

为了确保在调用 CAGinit 函数之前 CAGScript.js 已加载并执行,最可靠的方法是在 CAGScript.js 内部调用该函数。

CAGScript.js:



    ...
    /*
    your code
    */
    function CAGinit(){
    ...
    }
    ...
    /* last line */
    CAGinit();

Run Code Online (Sandbox Code Playgroud)

然后,在主文件中调用 getScript():

 

    $.getScript("CAGScript.js");

Run Code Online (Sandbox Code Playgroud)