jQuery事件的竞争条件

时间:2013-11-06 15:58:34

标签: javascript jquery race-condition

我有一个带有锚标签的元素列表,其href我在悬停时动态填充。这是我的绑定代码:

$('.charts-container').on('mouseenter', '.track', function(e) {
  Itunes.populateDownloadLink(e);
}

以下是触发事件时触发的代码:

var ITunes = {
  populateDownloadLink: function(e) {
 e.preventDefault();
 trackDownloadLink = jQuery(e.currentTarget).find('.itunes-download a');
   if (trackDownloadLink.attr('href') == '#') {
      apiURL = ITunes.getApiUrl(trackDownloadLink);
      // retrieve iTunes download link from iTunes API
      jQuery.getJSON(apiURL, function(data) {
         if (data.results.length > 0) {
            trackDownloadLink.attr('href', data.results[0].trackViewUrl);
       }
  });
}

这在很大程度上起作用,除非我在元素之间快速悬停。有时,当发生这种情况时,链接似乎会搞砸了。例如,另一个元素上方的元素将有一个链接,当我快速盘旋它时,它由下面的元素生成。似乎存在某种竞争条件,即元素占用生成的第一个URL,即使它不是生成URL的元素。我发现这很奇怪,因为我正在使用e.currentTarget,根据我的理解,应始终引用函数绑定的元素,而不是鼠标当前所在的位置,甚至是触发事件的确切元素注册。

1 个答案:

答案 0 :(得分:1)

问题似乎是您将trackDownloadLink声明为全局变量,您需要使用populateDownloadLink声明它作为var方法的局部变量。< / p>

如果您将其用作全局变量,假设您将鼠标悬停在链接1上,则trackDownloadLink将引用相应的锚元素,并发送ajax请求以获取href值,然后在ajax完成后你将鼠标悬停在link2上,现在全局变量trackDownloadLink指的是link2中的锚而不是link1,然后第一个ajax返回,此时执行trackDownloadLink.attr('href', data.results[0].trackViewUrl);时ajax完成{{ 1}}指的是第二个链接,而不是第一个链接。

trackDownloadLink