Javascript回调函数范围?

时间:2011-04-02 22:58:06

标签: javascript callback scope anonymous-function

我有一个javascript函数,它有一个回调,然后是一个匿名函数,然后是另一个回调,并且该范围出现了问题。参数callbackFunc保留其第一个函数调用的值,而不使用第二个函数调用中传递的新值。

function IsReady(callbackFunc) {   
    if (!IsValid()) return false;
    IsConnected(function () {
        if (typeof (callbackFunc) == 'function')
            callbackFunc();
        return true;
    });    
}

function IsConnected(validCallbackFunc) {
$.post("IsConnected", function (data) {
    if (data.IsValid) {
        if (validCallbackFunc && typeof (validCallbackFunc) == 'function')
            validCallbackFunc();
    }
});
}

$('#SaveButton').click(function () {
    IsReady(SaveInvoice); // works       
});

$('#ExportButton').click(function () {
    // works only if IsConnected() is true     
    // otherwise SaveInvoice is called again
    IsReady(ExportInvoice);  
});

function SaveInvoice() {}
function ExportInvoice() {}

在某些情况下,当我单击ExportButton时,将运行SaveInvoice函数而不是ExportInvoice函数。我猜这是一个范围问题 - 以某种方式保留了callbackFunc的旧值。但由于回调+匿名函数+另一个回调的混合,我不太明白它。我没有写这段代码,但我必须解决它。我有什么办法可以在IsReady()结束时清除callbackFunc的值吗?

如果IsConnected()为true,则

IsReady(ExportInvoice)有效。如果IsConnected()为false,则结果是SaveInvoice()被执行,而实际上什么都不会发生(因为它没有连接)。

1 个答案:

答案 0 :(得分:1)

callbackFunc函数的两次不同调用之间无法保留IsReady值。

在您的代码中,每次执行单击事件处理程序时,都会在调用IsReady时创建 new 范围。每个范围都有自己的本地参数callbackFunc。每个作用域都将定义传递给IsConnected的匿名函数,其中驻留在闭包中的callbackFunc变量。

所以这不是范围问题。

为了证明这一点,我在这里模拟了您的代码:http://jsfiddle.net/pwJC7/

在您的代码中,您将讨论IsConnected返回值。这个函数实际上没有返回任何东西。连接状态似乎是通过ajax调用来检查的,该调用返回带有IsValid属性的XML或JSON数据(在小提琴中由$_post模拟)。

也许你的问题是由于这个异步调用。但是,如果您使用您提供的JavaScript代码点击ExportInvoice按钮,则无法调用SaveInvoice函数。