2013-06-27 5 views
0

Я, вероятно, ищу что-то невозможное, но в любом случае давайте попробуем. Пожалуйста, рассмотрите следующий псевдо-код, который выполняет некоторую условную, удаленную операцию, которая выполняет обратный вызов после завершения. Но код в функции обратного вызова должен быть выполнен, даже если дистанционное управление не необходимое:Хороший синтаксис для анонимной функции, которая называется условно

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

Это не проблема закрытия. Предполагая, что «удаленная операция» означает «асинхронная операция», то это связано с обработкой асинхронных ответов.

Наверняка анонимные функции могут использоваться (и обычно будут) в этой ситуации, но помните, что «анонимная функция» - это , а не - синоним слова «закрытие». 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"); 
    }); 

Конечно, вы могли бы реорганизовать код в одну функцию, если вы хотели, но это, возможно, легче понять, как две функции, как указано в этом вопросе.

+0

Извините за причинение путаницы. Я имел в виду анонимные функции - я обновил название только сейчас. Что касается PHP, я даже не знал, что у него такие конструкции ... :-) Спасибо за хорошее решение. –