我可能正在寻找一些不可能的东西,但无论如何我们试一试。请考虑以下执行某些条件远程操作的伪代码,该代码在完成时执行回调。但是,即使不需要远程操作,也需要执行回调中的代码:
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 :(得分:0)
In可以简化:
var finallyFunction = function {
doSomeCleanup();
doSomeMoreCleanup();
setSomeStatus();
}
if (needsToSave)
performRemoteOperation(operationParameters, finallyFunction);
else
finallyFunction();
答案 1 :(得分:0)
这不是真正的封闭问题。假设“远程操作”意味着“异步操作”,那么它与处理异步响应有关。
当然,在这种情况下可以(并且通常会)使用匿名函数,但请记住“匿名函数”不是“闭包”的同义词。 Forgegt(几乎)你在PHP学到的一切,这不是词法闭包的好学习基础。
如果我的假设是正确的,而且我们确实在讨论异步性,那么jQuery的延迟/承诺会产生一个相当简洁的解决方案。
// 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");
});
当然,如果您愿意,可以将代码重构为单个函数,但如果问题中所示,它可以更容易理解为两个函数。