变量值未正确设置

时间:2013-02-27 14:21:50

标签: jquery global-variables getjson

在getJSON函数中未正确设置变量值。变量$ videoId在第一个警报中显示396和397。

但是在第二个警报中,值397显示两次。

我在这里遗漏了什么?我在这里找不到任何其他帖子来讨论这类问题。如果是这样,请指点我。

以下是jQuery代码。

 $( "div .ow_video_list_item").each(function(){         
     $videoId = $(this).children("a").attr("href").split("/")[5];
     alert($videoId);    ==> First Alert

     $.getJSON("video/get-embed/" + $videoId + "/", function (data)   
     {                        
         $.each(data, function (key, code) {                                  
             alert($videoId);   ==> Second Alert
         });       
     });  

  });

以下是HTML代码:

<div class="ow_video_list_item ow_small">
    <a href="http://site.com/video/396">Video 1</a>
</div>

<div class="ow_video_list_item ow_small">
    <a href="http://site.com/video/397">Video 2</a>
</div>

4 个答案:

答案 0 :(得分:1)

假设$videoLink实际上是$videoId,正如评论所指出的那样:

这是因为getJSON方法是异步的,你正在处理javascript闭包。执行getJSON回调时:

function (data)   
     {                        
         $.each(data, function (key, code) {                                  
             alert($videoId);   ==> Second Alert
         }); 

你已经在第一个循环中循环,$ videoId取了最后一个值,因此显示397两次。

了解javascript闭包在这里的工作原理:How do JavaScript closures work?

答案 1 :(得分:1)

执行getJson方法时,使用异步代码。在这种情况下,您为$videoID提供的最后一个值是397,因此在两个回调中都是警报值。有几种方法可以解决这个问题。例如,您可以返回从videoID操作检索到的“数据”中的getJson值,并使用它alert(data.videoID)。或者,您可以使用具有适当键的值数组,而不是使用简单的整数变量。例如,它可以是索引(i in $().each(function(i,e) {}))。你需要找到一种让它像那样工作的方法。我认为data.id是最简单的方法!希望它有所帮助。

答案 2 :(得分:1)

关于getJson的异步性质的其他评论是正确的。但大多数情况下,问题是您使用全局变量$ videoId。 如果你替换:

$videoId = $(this).children("a").attr("href").split("/")[5];

通过

var $videoId = $(this).children("a").attr("href").split("/")[5];

即使使用异步方法,你也没问题。

答案 3 :(得分:1)

一些事情。

  • 在你的代码中没有定义$ videoId,我假设$ videoLink真的应该是$ videoId。供将来参考,如果可能更容易做这些事情来访问该数据点

<a href="http://site.com/video/396" data-video-id="396">Video 1</a>

通过这种方式,您可以使用$(element).data('videoId')轻松访问该视频ID。还有其他策略,比如使用类。

  • 如果$ videoLink在代码示例中不应该是$ videoId,则$ videoId定义在该函数范围之外的某处。 JS中的范围/闭包有很多资源。如果你正在做大量的JS开发工作,我会建议Javascript: The good parts

  • 回到假设$ videoLink实际上是代码示例中的$ videoId。你在.each循环中分配它的值但是该变量本身并没有在该函数内“关闭”。它可以是全局的,也可以在每个循环范围之外的其他位置定义。在var语句前面抛出$videoLink =以保持该var包含。

  • 另一个潜在问题是您正在调用对服务器的异步调用,但取决于该异步调用范围之外的变量。大多数情况下,这些调用将是毫秒,但理解正在发生的事情的一个好方法是在心理上逐步执行代码并假装每个服务器调用将花费1分钟。在您的示例中,外部循环运行一次,获取396的id然后触发AJAX请求,然后再次循环并对id 397执行相同的操作。服务器在第二次ajax请求所花费的时间内没有响应开火所以你现在有2个ajax请求。一分钟后他们回来看看,你的$ variableLink变量的值为397,因为它是在ajax回调函数之外定义的。这个解决方案?有几个。您可以使用从服务器返回的一些数据来满足您的需要,也可以保留从服务器访问的潜在视频的数组/哈希值。

还有其他方法可以做到这一点,但不知道除了跟踪变量之外你要做的事情的确切用例,很难说。但这应该为你提供一个很好的起点。