2015-09-09 2 views
1

У меня есть функция, которая отправляет некоторые данные. В зависимости от состояния некоторого булева, я бы не захотел представить эти данные. Однако вызывающий абонент всегда ожидает отложенного объекта в качестве возвращаемого значения для проверки .done() или .fail(). Кажется, вы не можете вернуть null или ничего не вернуть, когда что-то ожидает сделать/сбой (имеет смысл), поэтому я не знаю, как вернуться от этого асинхронного вызова.Возврат отложенного объекта или null

Я могу взломать объект $ .Deferred и немедленно разрешить/вернуть его, но это похоже на плохой дизайн. Я не могу изменить метод вызова здесь.

Как вернуть отложенный объект или какое-либо другое возвращаемое значение, которое удовлетворяет .done() или .fail() без использования отложенного объекта?

function foo(a) { 
    bar(a).done(function() { 
     console.log("done"); 
    }).fail(function() { 
     console.log("fail"); 
    }); 
} 

function bar(a) { 
    if (a){ 
     // Could create a $.Deferred and resolve it 
     return; 
    } 

    return doAsync(); 
} 

function doAsync() { 
    var defer = $.Deferred(); 
    defer.resolve(); 
    return defer.promise(); 
} 

foo(false); // fine 
foo(true); // error 

http://jsfiddle.net/ma4grjj4/2/

+7

* «Я могу взломать объект $ .Deferred и немедленно разрешить/вернуть его, но это похоже на плохой дизайн». * Совсем нет. –

+0

@FelixKling Хм, правда? То, что я хотел бы сделать в идеале, - это «foo» пропускать весь вызов «bar», но в «bar(). Done» должно происходить много всего, что должно произойти в обоих случаях. – BarryBones41

+1

Это именно то, что вы получаете с [немедленно разрешенным обещанием] (http://stackoverflow.com/questions/24794434/immediately-return-a-resolved-promise). Это не антипаттерн. – raina77ow

ответ

1

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

Я думаю, вы согласитесь, что делать что-то вроде следующего не имеет смысла:

function process(doNotProcess) { 
    if (doNotProcess) return; 

    //process 
} 

В приведенном выше примере, было бы больше смысла, чтобы просто не позвонить на process(), чтобы избежать обработки.

«То, что я бы в идеале в обув пропустить весь вызов бара, но много вещей происходит внутри бара(). Сделано, которое должно произойти в обоих случаях»

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

«Я могу взломать объект в $ .Deferred и немедленно разрешить/вернуть его, но, похоже, плохой дизайн.»

Создание отложенных объектов и их решение сразу же является стандартным подходом, когда вам необходимо стандартизировать использование API, который может иметь синхронную или асинхронную реализацию.

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

Смежные вопросы