2013-06-27 25 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,我甚至不知道它有這樣的構造...... :-)儘管如此,感謝一個不錯的解決方案。 –