可能的竞争条件?

时间:2014-04-04 13:54:27

标签: javascript race-condition

我有以下代码:

<HTML>

<HEAD>
  <SCRIPT>
  function myFunction(atlasTrackingURL)
  {
    var atlasURL = atlasTrackingURL;
    if (!atlasURL) return;

    //Build a cache busting mechanism
    var timestamp = new Date();
    var queryString = "?random=" + Math.ceil(Math.random() * 999999999999) + timestamp.getUTCHours() + timestamp.getUTCMinutes() + timestamp.getUTCSeconds();
    //Build the final URL
    atlasURL = atlasURL + queryString;

    if (!document.getElementsByTagName || !document.createElement || !document.appendChild)
      {return false;}
    else
      {     //Activate the JACTION call
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.onload = function()
        {
            document.getElementsByTagName("head")[0].appendChild(script);
        };
        script.src = atlasURL;
        return false;
      }
  }
  </SCRIPT>
</HEAD>

<BODY>

<a href="http://www.microsoft.com" onclick = "myFunction('http://view.atdmt.com/jaction/adoakb_PiggybackJSTest_1')">Test - Click Me</a>

</BODY>
</HTML>

它每次都在Internet Explorer中运行,但很少在Chrome和Firefox中运行。为什么会这样?

有趣的是,如果我用#替换URL(microsoft.com),它确实可以正常执行。我想知道在onclick函数加载之前href是否存在某种竞争条件。添加#会阻止href执行,因此onclick函数有时间触发。有什么方法可以解决这个问题吗?

我正在努力帮助客户弄清楚为什么他们的跟踪代码之一在这些浏览器中一直没有点击。应该有一个javascript文件可以在点击时执行(view.atdmt.com网址),但它只适用于IE,并且不会在FF和Chrome中启动。

我几乎肯定实际代码没有任何问题 - 因此我相信这些浏览器无法足够快地执行onclick并且首先执行着陆页。到达目标网页后,无法再调用onclick函数....

谢谢,

2 个答案:

答案 0 :(得分:1)

尝试在添加脚本之前等待加载:

script.onload = function()
{
    document.getElementsByTagName("head")[0].appendChild(script);
};
script.src = atlasURL;

答案 1 :(得分:0)

当您从函数返回true时,允许链接的默认操作,浏览器继续导航到该页面。

对于文档的更改和排队请求的确切情况可能会有所不同,因为它可以通过浏览器的实现来执行合理的操作,并且请求脚本而不执行此操作都在&#内39;合理。

当您离开页面时,您无法期望浏览器在当前页面中实际执行更多操作。有些浏览器可能会继续发生,直到新页面开始到达为止,有些浏览器可能暂停某些操作,因为它们会在响应到达时请求不再存在的页面的数据。

要使其在任何浏览器中都有效,您应该从函数返回false以防止链接被激活,并在导航到新页面之前等待脚本加载。

编辑:

在函数中添加一个参数来处理URL:

function myFunction(url, atlasTrackingURL)

使用onload事件导航脚本加载时的URL:

var script = document.createElement("script");
script.type = "text/javascript";
script.onload = function() {
  window.location.href = url;
};
script.src = atlasURL;
document.getElementsByTagName("head")[0].appendChild(script);
return false;

在事件处理程序中返回结果以停止激活链接:

<a href="http://www.microsoft.com" onclick = "return myFunction(this.href, 'http://view.atdmt.com/jaction/adoakb_PiggybackJSTest_1')">Test - Click Me</a>