1

在我的 javascript 的某个时刻,我有以下内容(使用 Modernizr 2.6.2):

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

它在大多数情况下都很好用,除了在 IE8 上,大约 3 次中的 1 次它首先执行回调,然后加载脚本。我在回调上添加了一个断点,并在 file.js 中添加了另一个断点。两个脚本都在执行,只是有时交换顺序。

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

我不是在寻找针对这种特定情况的解决方法。这是我真正想保持原样的众多实例之一。

编辑 1 - 新信息: 使用网络面板,我可以看到两个请求正在完成(这是预期的),但第一个请求总是返回空白。第二个请求带来了正确的内容。这在两个请求都完成后执行回调时工作正常,但有时回调是在第一个(空)和第二个请求之间执行的。那就是它崩溃的时候!

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

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

4

2 回答 2

2

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

Modernizr.load([{

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

function checkStatus(){
  if(filesLoaded == 2){
    //do stuff
  }else{
    setTimeout(checkStatus, 100);
  }
}
于 2013-11-11T17:27:33.563 回答
2

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

Modernizr load [A, B] 似乎在 A 之前执行 B,这怎么可能?

YepNopeJS:在微型 JS 文件完全加载之前触发回调

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


在阅读了这篇关于 IE 上遇到的不一致的好文章(在 yepnope 页面上引用)后,我想出了一个修复程序,该修复程序已通过 github 发送给 yepnope 维护人员:

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

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


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

//instead of
complete:function(){
    doStuff()
}
//try
complete:function(){
    setTimeout(doStuff, 0);
}
于 2013-11-18T03:26:58.853 回答