Synchronous [removed] statements?

2019-06-13 14:50发布

问题:

I am using xmlhttprequest (and eval) to dynamically load scripts. Next I evaluate the script and look to see if there are any other scripts to load. Along the way if any of the scripts cause and exception, the error message reported indicates the line number associated with eval, not with the actual error in the script.

On another question it was suggested I use <script> instead to get better error messages. Unfortunately, <script> is asynchronous, and I won't be able to control the order of loading of scripts (I need an onload callback).

How do I implement synchronous behaviour in <script> commands


Some more info as to what I aim to achieve

Every script has a list of other scripts it loads, stored in a list, lets call it _toLoad

Lets say we have a script 'Main.js' with a load list like so

_toLoad = [['A.js'] , ['B.js'] , ['C.js'] , ['D.js' , 'E.js' , 'F.js']]

Which states that once loaded, the file 'A.js' must be loaded next. Once 'A.js' is loaded, 'B.js' must be loaded next. Once 'B.js' is loaded, 'C.js' must be loaded next. Once 'C.js' is loaded, 'D.js' ,'E.js' , and 'F.js' must be loaded, in any order.

I could use <script> to load 'Main.js', evaluate it's _toLoad list and start loading the other scripts, in the correct order. But what happens if 'A.js' has several scripts it also loads? I want those to load in the background, and not to delay 'B.js' from loading

What if 'A.js' has a load list like so:

_toLoad = [['A2.js'] , ['B2.js'] , ['C2.js'] , ['D2.js' , 'E2.js' , 'F2.js']]

Is I would have to go through and issue <script> statements for those. It seems like a depth first approach, when I want a form of breadth first.

回答1:

One of the linked questions mentioned setting the innerHTML of the script tag element. I think this might do the trick

function load(toEval, callback){
    __global_callback = callback;

    var node = document.createElement('script');
    node.innerHTML = toEval + '; __global_callback()';
    document.getElementsByTagName('head')[0].appendChild(node);
}

load("console.log('before...');", function(){
    console.log('...and after');
});