2014-02-25 2 views
2

У меня есть функция в виде:Возвращение отложенного объекта обещания и разрешить его

$.get_members = function() { 
    var group_id = $('#gid').val(); 
    if($(this).val() == group_id) 
     return; 

    var deferr = $.Deferred(); 

    $.get(url) 
     .done(function() { 
      ... 
      deferr.resolve(); 
     }); 

    return deferr.promise(); 
} 

А теперь вопрос: как справиться с ситуацией, когда group_id == $(this).val()? Я хотел бы сделать просто:

var members_deferr = $.get_members(); 

members_deferr.done(function() { 
    ... 
}); 

Одна идея состоит в том, чтобы проверить тип возвращаемого значения, но не очень приятно. Вторая идея заключается в разрешении отложенных в setTimeout, но я не знаю, безопасно ли это.

Любые другие идеи?

ответ

4

Если в случае выбора group_id и у вас есть члены группы, вам просто нужно вернуть разрешенный deferrent. Обратный вызов done() будет вызываться сразу, нет необходимости проверять тип возврата. Что-то вроде этого:

$.get_members = function() { 
    var group_id = $('#gid').val(); 
    var deferr = $.Deferred(); 
    if($(this).val() == group_id) { 
    deferr.resolve(); 
    } 
    else { 
    $.get(url) 
     .done(function() { 
      ... 
      deferr.resolve(); 
     }); 
    } 

    return deferr.promise(); 
} 
+0

Как это работает? Я думал, что если я буду называть 'resolve()' перед связыванием функции с 'done()' обратным вызовом, 'done()', конечно, будет вызываться, но его еще не привязано (поскольку его связали после получения 'deffer.promise() '). Я ошибаюсь? – marxin

+0

Проверьте, он работает. Связывание обратных вызовов, таких как .done (...), сбой, всегда работает даже после разрешения/отклонения. Подумайте о реализации следующим образом: Deferred.done = function (callback) {if (this.state === 'pending') this.waitingDones.push (callback); else if (this.state === 'successed') callback(); } –

+0

Да, он работает как (не) ожидаемый :) Спасибо. – marxin

1

Я не совсем уверен, что вы пытаетесь сделать, если val == group_id. Это то, что вы имеете в виду?

$.getMembers = function() { 

    if ($(this).val() == $('#gid').val()) 
    { 
     return $.Deferred().reject().promise(); 
    } 

    return $.get(url).then(function() { 
     // ... 
    }).promise(); 
} 
0

Поздний ответ из-за загруженности заклинанием ...

Вопросительные намеки на плагин JQuery. Если это то, что вы хотите, то вы могли бы сделать что-то вроде этого:

(function($){ 
    var pluginName = 'get_members'; 
    $.fn[pluginName] = function(url, otherValue) { 
     var $this = $(this).eq(0), 
      data = $this.data(pluginName); 
     if(!data) { 
      data = {}; 
      $this.data(pluginName, data); 
     } 
     if(otherValue === undefined || $this.val() !== otherValue) { 
      if(data.jqXHR) { 
       data.jqXHR.abort(); 
      } 
      data.jqXHR = $.get(url).done(function(response, textStatus, jqXHR) { 
       ... 
      }); 
     } 
     return data.jqXHR || $.Deferred().reject(pluginName + ': conditions for fetching members have not been met'); 
    } 
})(jQuery); 

//Normal usage 
var promise_of_members = $("#myInputElement").get_members('http://my/url', $("#gid").val()); 
//or 
var promise_of_members = $("#myInputElement").get_members('http://my/url', 'myComparisonString'); 

//Force get 
var promise_of_members = $("#myInputElement").get_members('http://my/url'); 

Несколько проектных решений должны были быть сделаны в письменной форме на это, так что вы могли бы в конечном итоге с чем-то немного другой, в зависимости от того, что именно вы хотите, чтобы делать и сколько контролировать подробное поведение, которое вы хотите иметь.

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