我正在以循环方式从多个来源异步轮询数据,并希望在所有这些民意调查结束后重复轮询。我试图使用jQuery Deferred对象和“always”重复我的轮询,如下面的代码所示:
function makeAjaxCall(region) {
var params = {
'action': POLLER.action,
},
url = POLLER.region_to_url[region];
return $.ajax({
dataType: "json",
url: url,
data: params,
success: (function(region) {
return function(result, status) {
handleAjaxResult(result, status, region);
};
})(region),
error: (function(region) {
return function(jqXHR, textStatus, errorThrown) {
handleAjaxError(jqXHR, textStatus, errorThrown, region);
};
})(region)
});
}
function nextPoll() {
if(!polling) {
return;
}
var requests = [];
$.each(POLLER.regions, function(i, region) {
requests.push(makeAjaxCall(region));
});
$.when.apply($, requests)
.always(function() {
log("deferred.always ", this)
updateSummary();
var delay = POLLER.POLLER_INTERVAL_MS;
if (delay != 0) {
pollerTimeout = setTimeout(nextPoll, delay);
}
}).fail(function() {
log("fail for ",this)
});
}
我的问题是,当我的一个民意调查失败时,会调用“always”块。我可能会错误地假设在所有请求完成或失败后应该调用“always”。我打算让它以这种方式运作,所以任何关于不同的,可能更简单的方法的提示都会很棒。
答案 0 :(得分:0)
感谢@Ross的帮助。我设法修改我的代码以删除Deferred对象的使用,并且只跟踪返回了多少ajax请求,因此在ajax调用的成功和错误处理程序中,我也总是调用跟踪轮询数量的相同函数
function makeAjaxCall(region) {
var params = {
'action': POLLER.action,
},
url = POLLER.region_to_url[region];
$.extend(params, POLLER.filters);
return $.ajax({
dataType: "json",
url: url,
data: params,
success: (function(region) {
return function(result, status) { handleAjaxResult(result, status, region); };
})(region),
error: (function(region) {
return function(jqXHR, textStatus, errorThrown) { handleAjaxError(jqXHR, textStatus, errorThrown, region); };
})(region)
});
}
function handleAjaxResult(result, status, region) {
POLLER.data[region] = results.data;
afterAjaxResult();
}
function handleAjaxError(jqXHR, textStatus, errorThrown, region) {
POLLER.ajax_errors[region].count++;
afterAjaxResult();
}
function nextPoll() {
if(!polling) {
return;
}
POLLER.round_robin = 0;
$.each(POLLER.regions, function(i, region) {
makeAjaxCall(region)
});
}
function afterAjaxResult() {
POLLER.round_robin++;
if(POLLER.regions.length === POLLER.round_robin) {
updateSummary();
var delay = POLLER.POLLER_INTERVAL_MS;
if (delay != 0) {
pollerTimeout = setTimeout(nextPoll, delay);
}
}
}
有关示例,请参阅此jsFiddle。
答案 1 :(得分:0)
我写了一个$.when
的扩展名来完成这个。
此扩展程序将所有成功和失败视为进度事件。 在所有承诺完成后,全球承诺得以解决 如果没有错误。否则,全球承诺将被拒绝。
$.whenAll
- https://gist.github.com/4341799(tests)
样本用法:
$.whenAll($.getJSON('foo'), $.getJSON('bar'))
.then(
doneCallback
,failcallback
// progress callback
// the only problem is $.ajax.done/fail states call their callbacks
// with params in different locations (except for state)
,function(data, state, jqXhr) {
if (state == 'success') {
// do happy stuff
}
else { // error (fail)
// `data` is actually the jqXhr object for failed requests
// `jqXhr` is the text of the error "Not Found" in this example
}
}
)
;