2013-06-27 29 views
0

我可能正在寻找一些不可能的东西,但无论如何,让我们试试看。请考虑执行一些有条件的远程操作的以下伪代码,该代码在完成时执行回调。但在回调的代码需要即使远程操作不neccessary被执行:有条件地称为匿名函数的良好语法

if (needsToSave) 
{ 
    performRemoteOperation(operationParameters, function() { 
    doSomeCleanup(); 
    doSomeMoreCleanup(); 
    setSomeStatus(); 
    }); 
} 
else 
{ 
    doSomeCleanup(); 
    doSomeMoreCleanup(); 
    setSomeStatus(); 
} 

我发现这个代码特别丑陋和难以管理。在相关的无条件块中省略对回调块的更改很容易。在某些命名函数中有一个明显的包装代码解决方案,但它不再是匿名内联代码。 :-)

我能想到的最好的是在一些有条件的调用者来包装整个代码:

function conditionalCall(condition, action, callback) 
{ 
    if (condition) 
    action(callback) 
    else 
    callback() 
} 

然后,我的代码将均价为:

conditionalCall(needsToSave, 
    function(_callback) { 
    performRemoteOperation(operationParameters, _callback) 
    }, 
    function() 
    { 
    doSomeCleanup(); 
    doSomeMoreCleanup(); 
    setSomeStatus(); 
    } 
); 

...但我不完全确定,这是否更具可读性和可管理性。特别是当涉及大量本地/远程/回调参数/闭包变量或者需要在另一个呼叫的回调中“嵌入”一个远程呼叫时。我希望在这种情况下可以使用更好的语法。

回答

0

在可simpified:

var finallyFunction = function { 
    doSomeCleanup(); 
    doSomeMoreCleanup(); 
    setSomeStatus(); 
}  

if (needsToSave)  
    performRemoteOperation(operationParameters, finallyFunction); 
else 
    finallyFunction(); 
+0

谢谢,但我表明,命名函数不是一个选项在这里。 :-) –

0

这是不是一个真正的封闭问题。假设“远程操作”是指“异步操作”,那么它就是处理异步响应。

可以肯定,匿名函数(S)可以(并且通常会)在这种情况下使用,但请记住,“匿名函数”是为“关闭”的代名词。 Forgegt(几乎)所有你在PHP中学到的东西,这对于词法关闭来说并不是很好的学习基础。

如果我的假设是正确的,而且我们确实在谈论异步性,那么jQuery的Deferreds/promise就是一个相当整洁的解决方案。

// First make sure performRemoteOperation() returns a promise, 
function performRemoteOperation(operationParameters) { 
    ... 
    return promise;//for example a jqXHR object, as generated by $.ajax() and its shorthand methods. 
} 

function myFunction(needsToSave) { 
    var p = needsToSave ? performRemoteOperation(operationParameters) : $.Deferred.resolve().promise(); 
    //At this point `p` is either an unresolved promise returned by performRemoteOperation(), or a resolved promise generated in the line above. 
    p.done(function() { 
     //This function fires when the remote operation successfully completes, or immediately if `needsToSave` was false. 
     doSomeCleanup(); 
     doSomeMoreCleanup(); 
     setSomeStatus(); 
    }); 
    return p;//A promise is returned for good measure, in case further chaining is necessary where myFunction() is called. 
} 

//Sample calls 
myFunction(false); 

myFunction(true).then(function() { 
     alert("successfully saved"); 
    }, function() { 
     alert("error: something went wrong"); 
    }); 

当然,你可以重构代码到一个单一的功能,如果你希望,但它无疑更容易理解为两个功能,如问题指出。

+0

抱歉造成混淆。我的意思是匿名功能 - 我刚刚更新了标题。至于PHP,我甚至不知道它有这样的构造...... :-)尽管如此,感谢一个不错的解决方案。 –