如何控制Javascript执行顺序?

时间:2022-02-25 20:14:23

I'm having some concurrency issues with a webpage I'm building. Basically, I have three script files that I'm using to hold some data:

我正在构建一个网页,我遇到了一些并发问题。基本上,我有三个脚本文件,我用来保存一些数据:

script1.js:

var myValue = 1;

script2.js:

var myValue = 2;

script3.js:

var myValue = 3;

And I have one page, mypage.html that basically looks like this:

我有一个页面,mypage.html,基本上看起来像这样:

<html>
<script>
   function get_number()
   {
     var script_file = GetQueryStringValue( "run" );
     e = document.createElement('script');
     e.type='text/javascript';
     e.src = script_file + ".js"
     head.appendChild( e );

     document.write( myValue );
   }
</script>
<body onload="get_number()">
   <div onclick="get_number()">Click me!</div>
</body>
</html>

The main idea with this page is that you would query it like this: mypage.html?run=script1 which would tell the get_number() function to dynamically insert script1.js in to mypage.htm. Then, I call get_number() to display the value loaded from the script.

这个页面的主要思想是你会这样查询:mypage.html?run = script1,它会告诉get_number()函数动态地将script1.js插入到mypage.htm中。然后,我调用get_number()来显示从脚本加载的值。

Now, I've stripped down the above to what I think are the relevant parts and I've left out a bunch of stuff, obviously. My actual code loads a large array of values and is more interesting... But, I'm hoping someone can help me out with this regardless.

现在,我已经将上述内容简化为我认为的相关部分,显然我遗漏了很多东西。我的实际代码加载了大量的值并且更有趣......但是,我希望有人可以帮助我解决这个问题。

What I'm finding is that in IE, the number displays correctly.

我发现在IE中,数字显示正确。

In Firefox, Chrome and Safari, I get an error that myValue is undefined. However, if I click the Click me div that I created, the number displays correctly. So, I know I'm correctly loading the javascript external file. But, it just isn't loaded in time for my get_number() function to work correctly onload.

在Firefox,Chrome和Safari中,我收到一个错误,即myValue未定义。但是,如果单击我创建的Click me div,则数字会正确显示。所以,我知道我正在加载javascript外部文件。但是,它只是没有及时加载我的get_number()函数正确工作onload。

Now, I hacked up my file a little so that the get_number function looks like this:

现在,我稍微修改了我的文件,以便get_number函数如下所示:

 function get_number()
 {
   var script_file = GetQueryStringValue( "run" );
   e = document.createElement('script');
   e.type='text/javascript';
   e.src = script_file + ".js"
   head.appendChild( e );

   setTimeout( function() { document.write( myValue ), 10 } );
 }

The setTimeout delays enough for the DOM to be updated and the javascript to be loaded in most cases. But, this is a total hack. Firefox tends to load this 'improved' code correctly all the time while Chrome and Safari manage to get the value about 50% of the time.

setTimeout延迟到足以使DOM更新并且在大多数情况下加载javascript。但是,这完全是黑客攻击。 Firefox倾向于一直正确地加载这个“改进的”代码,而Chrome和Safari设法在大约50%的时间内获得价值。

So, I guess I'm wondering, is there a better way to accomplish what I'm trying to do here? It's very important that the value be driven externally (by the query string), but other than that requirement, I'm very flexible.

所以,我想我想知道,有没有更好的方法来完成我在这里尝试做的事情?从外部驱动值(通过查询字符串)非常重要,但除了该要求之外,我非常灵活。

2 个解决方案

#1


Could you possibly add a function call to your script files, so that when they're run, they call the function that does your

你是否可以为你的脚本文件添加一个函数调用,这样当它们运行时,它们会调用你的函数

document.write( myValue );

So that script1.js would be

所以script1.js会是

var myValue = 1;
scriptLoaded();

and your main file would have:

你的主文件将有:

function scriptLoaded(){
   document.write( myValue );
}

#2


This method of dynamically loading script files using DOM methods like head.appendChild is asynchronous, meaning that the page does not wait for it to load before running any further code. If you did not want this asynchronous behaviour, you could load them with regular elements in your HTML, or you could mess around with a 'synchronous' XMLHttpRequest to grab it and eval() to run it.

这种使用head.appendChild等DOM方法动态加载脚本文件的方法是异步的,这意味着在运行任何进一步的代码之前,页面不会等待它加载。如果您不想要这种异步行为,可以在HTML中使用常规元素加载它们,或者您可以使用“同步”XMLHttpRequest来抓取它并使用eval()来运行它。

You probably don't want to do that, though, because being asynchronous makes the entire page load faster, anyway. You will probably just need to add some logic that waits for the dynamically loaded script to have loaded before you go on with the next bit of code. This may, however, involve polling using setInterval() until you notice a variable from the included script has been defined. Or, you could add code in the included script that calls a method to whatever has been waiting for it.

但是,您可能不希望这样做,因为无论如何,异步会使整个页面加载速度更快。在继续下一段代码之前,您可能只需要添加一些等待动态加载的脚本加载的逻辑。但是,这可能涉及使用setInterval()进行轮询,直到您注意到已定义包含的脚本中的变量为止。或者,您可以在包含的脚本中添加代码,该代码将方法调用到等待它的任何方法。

Or, you could look at how jQuery does something similar, look for where the ajax method is defined, specifically these parts...

或者,您可以看看jQuery如何做类似的事情,寻找定义ajax方法的位置,特别是这些部分......

var script = document.createElement("script");

// then later ...

script.onload = script.onreadystatechange = function(){
    if ( !done && (!this.readyState ||
    this.readyState == "loaded" || this.readyState == "complete") ) {

        // do processing
            head.removeChild( script );
    }
};

// ...

head.appendChild(script);

#1


Could you possibly add a function call to your script files, so that when they're run, they call the function that does your

你是否可以为你的脚本文件添加一个函数调用,这样当它们运行时,它们会调用你的函数

document.write( myValue );

So that script1.js would be

所以script1.js会是

var myValue = 1;
scriptLoaded();

and your main file would have:

你的主文件将有:

function scriptLoaded(){
   document.write( myValue );
}

#2


This method of dynamically loading script files using DOM methods like head.appendChild is asynchronous, meaning that the page does not wait for it to load before running any further code. If you did not want this asynchronous behaviour, you could load them with regular elements in your HTML, or you could mess around with a 'synchronous' XMLHttpRequest to grab it and eval() to run it.

这种使用head.appendChild等DOM方法动态加载脚本文件的方法是异步的,这意味着在运行任何进一步的代码之前,页面不会等待它加载。如果您不想要这种异步行为,可以在HTML中使用常规元素加载它们,或者您可以使用“同步”XMLHttpRequest来抓取它并使用eval()来运行它。

You probably don't want to do that, though, because being asynchronous makes the entire page load faster, anyway. You will probably just need to add some logic that waits for the dynamically loaded script to have loaded before you go on with the next bit of code. This may, however, involve polling using setInterval() until you notice a variable from the included script has been defined. Or, you could add code in the included script that calls a method to whatever has been waiting for it.

但是,您可能不希望这样做,因为无论如何,异步会使整个页面加载速度更快。在继续下一段代码之前,您可能只需要添加一些等待动态加载的脚本加载的逻辑。但是,这可能涉及使用setInterval()进行轮询,直到您注意到已定义包含的脚本中的变量为止。或者,您可以在包含的脚本中添加代码,该代码将方法调用到等待它的任何方法。

Or, you could look at how jQuery does something similar, look for where the ajax method is defined, specifically these parts...

或者,您可以看看jQuery如何做类似的事情,寻找定义ajax方法的位置,特别是这些部分......

var script = document.createElement("script");

// then later ...

script.onload = script.onreadystatechange = function(){
    if ( !done && (!this.readyState ||
    this.readyState == "loaded" || this.readyState == "complete") ) {

        // do processing
            head.removeChild( script );
    }
};

// ...

head.appendChild(script);