【问题标题】:closure inside a for loop - callback with loop variable as parameter [duplicate]for循环内的闭包-以循环变量作为参数的回调[重复]
【发布时间】:2011-10-22 04:14:14
【问题描述】:

我在循环中使用 jQuery“GET”从服务器获取多个结果。我想将循环索引作为固定参数包含在回调中,但它不起作用。

(我听从了this article 的建议如何去做。)

但是,我在回调中得到的值完全不是我所期望的——而不是每个循环索引值,它总是等于索引的退出值。

即。此处的代码片段为回调的每次执行打印出“16”。如何让它打印 1、2、3...(我意识到顺序可能不同,这很好)

除了下面的代码之外,我还尝试了几种方法来指定回调函数,例如。 function(data, textStatus) { return test(data, textStatus, idx); }, 'text');

这应该如何工作?

function test(data, textStatus, siteNo)
{
    console.log("siteNo=" + siteNo);
}

function loadConfigLists()
{
    var siteReport;
    // retrieve site configuration
    jQuery.get("svGetSiteConfig.php", function(data, textStatus) 
    {
        // retrieve port configuration for all sites
        for (var idx=1; idx<=15; idx++)
        {
            var probeIP = siteConfigArray[idx].siteIP;
            if (probeIP != "" && probeIP != null)
            jQuery.get("svGetPortInfo.php?svSiteIpAddr=" + probeIP+"&s="+idx, 
                    function(data, textStatus) { test(data, textStatus, idx); }, 'text'); 
            else // IP value is blank
                siteConfigArray[idx].portManifest = null;
        }
        }
    }, 'text'); 
}

【问题讨论】:

    标签: javascript jquery closures jquery-callback


    【解决方案1】:

    这是一个非常标准的闭包问题。当你这样做时:

    function(data, textStatus) { test(data, textStatus, idx); }
    

    您正在绑定对 idx 的引用,但没有绑定到 idx 的值。因此,当您的回调被调用时,循环将完成,idx 在您绑定的所有回调中将是 16。

    通常的解决方案是通过函数调用强制评估idx

    function build_callback(idx) {
        return function(data, textStatus) {
            test(data, textStatus, idx);
        };
    }
    
    // And then...
    
    jQuery.get("svGetPortInfo.php?svSiteIpAddr=" + probeIP+"&s="+idx, build_callback(idx), 'text');
    

    如果你想把它放在一起,你也可以用一个自执行函数内联函数:

    for (var idx=1; idx<=15; idx++)
        (function(idx) {
            var probeIP = siteConfigArray[idx].siteIP;
            if (probeIP != "" && probeIP != null)
                jQuery.get("svGetPortInfo.php?svSiteIpAddr=" + probeIP+"&s="+idx, 
                    function(data, textStatus) { test(data, textStatus, idx); }, 'text'); 
            else // IP value is blank
                siteConfigArray[idx].portManifest = null;
        })(idx);
    

    函数调用会在调用函数时为您提供idx 的值,这就是您想要的idx 的值。

    【讨论】:

    • 谢谢,我发现一个更方便的方法是将每个 function() { blahblah that uses var i} 转换为 (function(ii){return function(){ 旧代码但将 i 更改为 " ii" }})(i);
    猜你喜欢
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    • 2020-09-25
    • 1970-01-01
    • 1970-01-01
    • 2020-04-05
    • 2018-12-26
    相关资源
    最近更新 更多