Modernizr.load callback executing before loaded script

两盒软妹~` 提交于 2020-01-16 04:00:10

问题


At a certain point on my javascript I have the following (using Modernizr 2.6.2):

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

It works great most of the time, except on IE8, about 1 time out of 3 it executes the callback first then the script being loaded. I am adding a break point on the callback and another inside file.js. Both scripts are being executed, just swapping the order at times.

I tried to isolate and reproduce the error, but I couldn't. It works fine every time when I have only this code on the page (using the exact same Modernizr file). For that reason I believe something else on my project could be interfering, but I have no clue on what to look next along the 10000 (really!) lines of js. Has anyone experienced anything similar or has any idea on what could cause this sort of behaviour?

I am not looking for a workaround for this specific case. This is one of many instances where I really would like to keep as is.

EDIT 1 - NEW INFO: Using the network panel, I can see that two requests are being done (which is expected), but the first request always returns blank. The second request brings up the correct content. That works fine when the callback is executed after both requests are complete, but sometimes the callback is executed between the first (empty) and second request. That is when it crashes!

EDIT 2 - NEW INFO: Ok seems like I can reproduce it now. To be 100% sure on my assumptions I would have to know the javascript engine in deep, which I don't, so I could be dead wrong, but here is what I found:

Request file1.js and file2.js. If file2 finishes loading while the engine is busy executing file1's callback, file2 execution goes somewhere at the end of the queue, which means after file2's callback.


回答1:


Try waiting for all of the files to load before firing the callbacks. Expand on the pattern below to suit your needs.

Modernizr.load([{

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

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



回答2:


After doing some research on the subject, I think this issue may be more common than it seems at first, but has been overlooked because it is context dependent, and has different ways of being described:

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


After reading this nice article (referenced on yepnope page), about the inconsistencies experienced on IE, I came up with a fix, which has been sent to yepnope maintainers via github:

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

I don't know whether it is going to be accepted or not, but it solved my problem.


As editing a library may not always be a good idea, I would suggest the following workaround:

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


来源:https://stackoverflow.com/questions/19781753/modernizr-load-callback-executing-before-loaded-script

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!