总是在jquery延迟后调用一个动作来解析一组请求

时间:2013-09-03 11:54:57

标签: javascript jquery arrays deferred

我正在以循环方式从多个来源异步轮询数据,并希望在所有这些民意调查结束后重复轮询。我试图使用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”。我打算让它以这种方式运作,所以任何关于不同的,可能更简单的方法的提示都会很棒。

2 个答案:

答案 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/4341799tests

样本用法:

$.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
      }
    }
  )
;