2014-01-30 2 views
3

Я не понимаю, как $.when работает во время сбоя при передаче нескольких вызовов AJAX. Если кто-то терпит неудачу, срабатывает ли вызов обратного вызова отказа? Кроме того, каков параметр fail, один за ajax, или он один сбой для всех?

$.when(
    $.ajax('/url1'), 
    $.ajax('/url2')) 
    .done(function (resp1, resp2) { 

    }).fail(function (??) { 

    }); 
+2

Если один отложенный сбой, оберточная $ .При сразу не удается, а также. – adeneo

+0

Имеет смысл, но в случае неудачи, как я могу узнать, какой из них не удалось? Есть ли один параметр сбоя на вызов AJAX или похоронен в одном параметре отказа? – TruMan1

+1

Если кто-то терпит неудачу, обнуление «$ .when» вызывается сразу, поэтому аргументы будут для первого «$ .ajax» терпеть неудачу, так как это будет вызвано внешнее 'fail()', имеет смысл ? – adeneo

ответ

4

Этого должно быть достаточно легко проверить прямо?

var d1 = $.Deferred(), d2 = $.Deferred(); 

$.when(d1, d2) 
    .fail(function (a, b) { 
     console.log(a, b); 
    }); 

d2.reject("hi!"); 

Выходной сигнал hi! undefined. Таким образом, передается только один аргумент.

http://jsfiddle.net/22b3L/

+0

Вам действительно не нужно проверять его, довольно очевидно, что если внешний 'fail()', прикрепленный к '$ .when', вызывается немедленно, если одна из отложенных внутри' $ .when' отклонена, то есть ajax сбой, аргументы будут переданы только из отказающего вызова ajax, так как нет гарантии, что остальные вызовы ajax будут завершены, а внешний 'fail()' вызывается сразу, поэтому нет никакого способа передать что-либо еще. – adeneo

+0

'когда (d1, d2) .done (функция (a, b) {})' имеет два аргумента. Способ обойти это требует: 'when_array ([d1, d2]). Done (spread (функция (a, b) {}))'. По моему опыту с jQuery у них есть очень хороший, но слегка произвольный синтаксический сахар. – Halcyon

0

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

$.when(
    $.ajax('/url1').fail(function() { console.dir('fail 1'); }), 
    $.ajax('/url2').fail(function() { console.dir('fail 2'); })) 
.done(function (resp1, resp2) { 

}).fail(function() { 
    console.dir('fail any'); 
}); 

Сбой любой будет вызываться сразу после одного из Аякса запросов не удалось, поэтому другой запрос конкретного сбой может быть называемый впоследствии.

1

.then() фактически принимает до трех аргументов (успех, неудача, прогресс). Вы можете использовать .fail(), как указано в других ответах, или вы можете сделать что-то вроде:

$.when(async).then(function success(resp) { 
     console.log('success'); 
    }, function fail(resp) { 
     console.log('fail'); 
    }); 
0

я работал через что-то подобное, и думал, что это может быть полезным для кого-то.

A CodePen playground with $.when

var d1 = $.Deferred().fail(function(a){ console.log('on fail 1', a) }), 
    d2 = $.Deferred().fail(function(a){ console.log('on fail 2', a) }), 
    d3 = $.Deferred().fail(function(a){ console.log('on fail 3', a) }); 
$.when(d1, d2, d3) 
.then(function (a, b, c){ 
    console.log('then: ', a, b, c); 
}) 
.fail(function (a, b, c) { 
    // only reports the first one that failed 
    console.log('fail: ', a, b, c); 
}) 
.always(function(a, b, c){ 
    console.log('always: ', a, b, c); 
}); 
d1.resolve("d1!"); 
d2.reject("d2!"); 
d3.reject("d3!"); 

A way to 'recover' from 1 failed in the array of deferreds

'use strict'; 
var getConfigRequestDef = $.Deferred(); 
var getConfigDef = $.Deferred(); 
var getStatusRequestDef = $.Deferred(); 
var getStatusDef = $.Deferred(); 
getConfigRequestDef.then(function (cfg) { 
    return getConfigDef.resolve(cfg); 
}, function (c) { 
    c.hasError = true; 
    getConfigDef.resolve(c); 
}); 
getStatusRequestDef.then(function (status) { 
    return getStatusDef.resolve(status); 
}, function (s) { 
    s.hasError = true; 
    getStatusDef.resolve(s); 
}); 
var results = $.when(getConfigDef, getStatusDef).then(function (config, status) { 
    console.log('The when\'s then: ', JSON.stringify(config), JSON.stringify(status)); 
}); 
var cfg = { 
    id: 10, 
    type: 'config', 
    hasError: false 
}; 
var statusObj = { 
    id: 30, 
    type: 'status', 
    hasError: false 
}; 
getConfigRequestDef.reject(cfg); 
getStatusRequestDef.reject(statusObj); 
Смежные вопросы