【问题标题】:Variable value not set correctly变量值未正确设置
【发布时间】:2013-02-28 00:32:32
【问题描述】:

在 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>

【问题讨论】:

  • 您在上面的代码中没有真正定义或设置一个名为 $videoId 的变量。
  • $videoLink 是拼写错误的 $videoId 吗?
  • 这是一个类型,我现在已经更正了。

标签: jquery global-variables getjson


【解决方案1】:

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

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

通过

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

即使使用异步方法,您也会没事的。

【讨论】:

  • 谢谢。这对我很有帮助。
【解决方案2】:

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

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

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

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

在这里看看 javascript 闭包是如何工作的:How do JavaScript closures work?

【讨论】:

  • 我真的很困惑学习clousers。对我来说似乎很复杂。感谢您指向此链接。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    几件事。

    • 在您的代码中没有定义 $videoId,我假设 $videoLink 确实应该是 $videoId。以供将来参考,是否可以更轻松地执行此类操作来访问该数据点

    &lt;a href="http://site.com/video/396" data-video-id="396"&gt;Video 1&lt;/a&gt;

    这样您就可以使用$(element).data('videoId') 轻松访问该视频 ID。为此还有其他策略,例如使用类。

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

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

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

    还有其他方法可以做到这一点,但是除了跟踪该变量之外,如果不知道您尝试做什么的确切用例,就很难说。但这应该给你一个很好的起点。

    【讨论】:

    • 感谢您的详细回复。这些确实帮助我理解了很多关于 jquery 范围的事情。
    猜你喜欢
    • 2021-06-07
    • 2015-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多