【问题标题】:When calling a function (in a loop) which uses a callback, how pass variables in and have them not change?当调用使用回调的函数(在循环中)时,如何传递变量并使它们不改变?
【发布时间】:2013-06-07 22:44:06
【问题描述】:

我在循环中为数组中的一堆 appId 调用 sendMessage。当我的回调被调用时,我需要检查错误,然后将出现错误的 appId 列入“黑名单”。问题是我尝试过的每一种方法都会导致回调中的 appId 在它被调用时发生变化!所以错误的 appId 会被列入黑名单。

我尝试了三个版本(见下文)。一个从不列入黑名单,另外两个做错了:

**这个黑名单错误的一个**

for ( var appName in apps )
{
    var app = apps[ appName ];

    var appId = app[ "appId" ];

    //Send message to that app
    chrome.runtime.sendMessage(
        app[ "appId" ],
        app,
        function (response)
        {
            var lastError = chrome.runtime.lastError;

            //Want to blacklist apps here
            if ( lastError && lastError.message.indexOf( "not exist" ) !== -1 )
            {
                //This blacklists the wrong one!
                myGlobalObject.addToTimeout( appId );
            }
        }
    );
}

**这个也黑名单错误的一个**

for ( var appName in apps )
{
    var app = apps[ appName ];

    var appId = app[ "appId" ];

    //Send message to that app
    chrome.runtime.sendMessage(
        app[ "appId" ],
        app,
        function (response)
        {
            var lastError = chrome.runtime.lastError;

            //Want to blacklist apps here
            if ( lastError && lastError.message.indexOf( "not exist" ) !== -1 )
            {
                //This blacklists the wrong one!
                myGlobalObject.addToTimeout( this[ "appId" ] );
            }
        }.bind( app )
    );
}

** 这个永远不会黑名单 **

for ( var appName in apps )
{
    var app = apps[ appName ];

    //Send message to that app
    chrome.runtime.sendMessage(
        app[ "appId" ],
        app,
        function (response)
        {
            var lastError = chrome.runtime.lastError;

            //Want to blacklist apps here
            if ( lastError && lastError.message.indexOf( "not exist" ) !== -1 )
            {
                //Somehow this NEVER blacklists it!
                myGlobalObject.addToTimeout( app[ "appId" ] );
            }
        }
    );
}

【问题讨论】:

    标签: javascript google-chrome google-chrome-extension google-chrome-devtools google-chrome-app


    【解决方案1】:

    对于稍后调用的回调,您需要在闭包中“冻结”变量的值。有几种方法可以做到这一点,这是一种使用立即调用函数的方法,该函数将变量作为参数传递,它们在该函数闭包中被捕获,因此它们的值在回调期间保持你想要的值:

    for ( var appName in apps )
    {
        var app = apps[ appName ];
    
        var appId = app[ "appId" ];
    
        // this creates a closure which captures the values of your variables
        // and holds them at the desired value until the callback is called
        // a separate and unique closure will be created
        // for each cycle of the for loop
        (function(appID) {
    
            //Send message to that app
            chrome.runtime.sendMessage(
                appId,
                app,
                function (response)
                {
                    // since this is called some time later
                    // variables outside this may have different values
                    // as the outer for loop continued to run
                    var lastError = chrome.runtime.lastError;
    
                    //Want to blacklist apps here
                    if ( lastError && lastError.message.indexOf( "not exist" ) !== -1 )
                    {
                        //This blacklists the wrong one!
                        myGlobalObject.addToTimeout( appId );
                    }
                }
            );
        })(appID);
    }
    

    【讨论】:

    • 谢谢,这是我一般问题的答案。事实证明,真正的问题只是我定义了一个 Function.prototype.bind 函数,这导致了错误。
    猜你喜欢
    • 1970-01-01
    • 2019-09-24
    • 2018-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多