2016-02-17 2 views
1

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

https://jsfiddle.net/3wtady9r/

function doAjax(file) { 
    var defer = $.Deferred(); 
    var fakeFile = file; 
    var data = null; 

    ajax(); 

    function ajax() { 
     return $.get(fakeFile) 
      .done(function(data) { 
       data = data; 
       defer.resolve(data); 
      }) 
      .fail(function() { 
       defer.fail(); 
      }) 
    } 
    return defer.promise(data); 
} 

var thisWillWork = ''; 

doAjax(thisWillWork) 
    .done(function() { 
     console.log('done') 
    }) 
    .fail(function() { 
     console.error('fail') 
    }) 
    .always(function() { 
     console.log('always') 
    }) 

var thisWontWork = 'fakeFile.html' 
doAjax(thisWontWork) 
    .done(function() { 
     console.log('done') 
    }) 
    .fail(function() { 
     console.error('fail') 
    }) 
    .always(function() { 
     console.log('always') 
    }) 

Когда я doAjax (thisWontWork) Я ожидаю, чтобы получить ошибку консоли, а также .always, но ни огня.

+1

Некоторые странные вещи. Вы вызываете 'ajax()' и игнорируете возвращаемое значение. У вас есть 'data = data;', но это только присваивается параметру, а не 'var data = null', поэтому' defer.promise (data) 'все еще передается' null' –

+0

Это выглядит как ужасно неудачная попытка для выполнения [отложенного антипаттерна] (http://stackoverflow.com/q/23803743/1048572) для меня. Не делай этого. – Bergi

ответ

2

Там есть куча разных вопросов.

  1. fail является способ подключения обработчиков получить вызывается, если обещание будет отклонено. До отклонять это, использование reject.

  2. Вы не хотите передавать data в defer.promise в конце.

  3. Вы не хотите или нуждаетесь в dataпеременная вообще, только аргументы вы получите в success.

  4. Поскольку вы никогда не используете значение, которое вы возвращаете из своей собственной функции ajax, нет необходимости возвращать его.

  5. JQuery-х ajaxуже возвращает обещание, что делает то, что делает ваше обещание, так что ваше обещание может быть просто удален полностью. Это часто бывает достаточно there's an antipattern named for it. Каждый раз, когда вы думаете, что вам нужно создать обещание, остановитесь и подумайте: у меня его уже есть? Конечно, иногда ответ отрицательный, но часто это да. :-)

С точки # 5, мы в конечном итоге с:

function doAjax(file) { 
    var fakeFile = file; 

    return $.get(fakeFile); 
} 

... что означает, конечно, что вам не нужно doAjaxна всех. Просто позвоните $.get.

Но если по каким-то причинам вы не разделяемым вам нужно собственное обещание, то просто указует 1-4:

function doAjax(file) { 
    var defer = $.Deferred(); 
    var fakeFile = file; 

    ajax(); 

    function ajax() { 
     $.get(fakeFile) 
      .done(function(data) { 
       defer.resolve(data); 
      }) 
      .fail(function() { 
       defer.reject(); 
      }); 
    } 
    return defer.promise(); 
} 
+0

Это действительно упрощенная версия того, что у меня происходит. Эта функция фактически передается в очередь, поэтому ее нужно возвращать следующим образом. Спасибо за исправления. – BarryBones41

+0

@ BarryBones41: Рад, что помогло. В конце концов, не имеет значения, находится ли это в очереди или что-то в этом роде, если оно возвращает обещание, которое выполняется с помощью 'data' или отклонено на основе результата' $ .get', тогда вы можете вернуть обещание с '$ .get'. –

1

Это должно быть defer.reject(); не defer.fail();

Также вы можете добавить данные в отклонение, как вы делали в defer.resolve().