Modernizr.load在加载脚本之前执行回调

时间:2013-11-05 04:03:11

标签: javascript modernizr yepnope

在我的javascript上的某一点上,我有以下内容(使用Modernizr 2.6.2):

Modernizr.load([{
    load: '/path/file.js',
    complete: function () {
        //do stuff
    }
}]);

它大部分时间都很好用,除了在IE8上,大约1次中有3次执行回调然后加载脚本。我在回调上添加了一个断点,另一个在file.js中。两个脚本都在执行,有时只是交换订单。

我试图隔离并重现错误,但我做不到。每次我在页面上只有这个代码时(使用完全相同的Modernizr文件),它工作正常。出于这个原因,我相信我的项目中的其他东西可能会干扰,但我不知道接下来沿着10000(真的!)js行看什么。有没有人经历过类似的事情,或者对可能导致这种行为的事情有任何想法?

我不是在寻找针对此特定情况的解决方法。这是我真正希望保留的许多情况之一。

编辑1 - 新信息: 使用网络面板,我可以看到正在完成两个请求(which is expected),但第一个请求始终返回空白。第二个请求会显示正确的内容。在两个请求完成后执行回调时工作正常,但有时在第一个(空)和第二个请求之间执行回调。那是它崩溃的时候!

编辑2 - 新信息:好吧好像我现在可以重现它。为了100%肯定我的假设,我必须深入了解javascript引擎,我不知道,所以我可能会出错,但这是我发现的:

请求file1.js和file2.js。如果file2在引擎忙于执行file1的回调时完成加载,则file2执行会在队列末尾的某处进行,这意味着在file2的回调之后。

2 个答案:

答案 0 :(得分:2)

尝试在触发回调之前等待加载所有文件。扩展下面的模式以满足您的需求。

Modernizr.load([{

load: '/path/file.js',
complete: function () {
    filesLoaded++;
    checkStatus();
}
}]);

function checkStatus(){
  if(filesLoaded == 2){
    //do stuff
  }else{
    setTimeout(checkStatus, 100);
  }
}

答案 1 :(得分:2)

在对这个问题进行一些研究之后,我认为这个问题可能比最初看起来更常见,但却被忽视了,因为它依赖于上下文,并且有不同的描述方式:

Modernizr load [A, B] seems to execute B before A, how is this possible?

YepNopeJS: callback triggered before tiny JS file is fully loaded

https://github.com/SlexAxton/yepnope.js/issues/195


在阅读了这个nice article(在yepnope页面上引用)之后,关于IE上遇到的不一致,我想出了一个修复程序,它已经通过github发送给了yepnope维护者:

http://github.com/SlexAxton/yepnope.js/pull/196

我不知道它是否会被接受,但它解决了我的问题。


由于编辑库可能并不总是一个好主意,我建议采用以下解决方法:

//instead of
complete:function(){
    doStuff()
}
//try
complete:function(){
    setTimeout(doStuff, 0);
}