在检查多个ajax请求完成时,我应该应用什么样的设计模式?

时间:2012-01-31 02:14:07

标签: javascript ajax design-patterns callback

我在一个函数中有3个ajax调用,并且checkAjaxCompletion检查每个ajax完成标志。

下面的代码是发送多个单独的ajax调用和interval方法检查完成标志以确定是继续还是保持间隔。 (我知道clearInterval没有显示,但重点是我想使用除间隔之外的东西)

目前的代码是:

function manyAjax() {

   setInterval( function() { checkAjaxCompletion(); } , 200);

   ajax1(); 

   ajax2();

   ajax3();

}

function ajax1() {
   //send ajax request to server and if success set flag to 1. Default is 0. Error is 2.
}

function ajax2() {
   //send ajax request to server and if success set flag to 1. Default is 0. Error is 2.
}

function ajax3() {
   //send ajax request to server and if success set flag to 1. Default is 0. Error is 2.
}

function checkAjaxCompletion() {

   if(ajax1_flag == 1 && ajax2_flag == 1 && ajax3_flag == 1) {
       //everything went success, do some process
   }
   else if(ajax1_flag == 2 || ajax2_flag == 2 || ajax3_flag == 2) {
       //some ajax failed, do some process
   }
   else {
      //all ajax have not been completed so keep interval i.e. do nothing here
   }
}

但我犹豫是否依赖于使用区间函数,因为调用它常常看起来像是浪费内存。必须有更好的方法。我在想observer pattern是否可以在这里应用,但是想听听意见。

4 个答案:

答案 0 :(得分:2)

观察者 - 通知器,如果你想要它 - 但是你的每个ajax调用很可能在完成时在javascript中有回调。为什么不在每个人的末尾打电话给checkAjaxCompletion(),如果你还在等待其他人,什么都不做?

答案 1 :(得分:1)

达斯汀·迪亚兹(Dustin Diaz)用example做得很好。

function Observer() {
  this.fns = [];
}

Observer.prototype = {
  subscribe : function(fn) {
    this.fns.push(fn);
  },

  unsubscribe : function(fn) {
    this.fns = this.fns.filter(
      function(el) {
        if ( el !== fn ) {
          return el;
        }
      }
    );
  },

  fire : function(o, thisObj) {
    var scope = thisObj || window;
    this.fns.forEach(
      function(el) {
        el.call(scope, o);
      }
    );
  }
};

出版商:

var o = new Observer;
o.fire('here is my data');

订阅者:

var fn = function() {
  // my callback stuff
};

o.subscribe(fn);

取消订阅:

var fn = function() {
  // my callback stuff
};

o.subscribe(fn);

答案 2 :(得分:1)

// ajax callback
            this.ajaxCallback = function(){                          
                $.ajax({            
                        type: "POST",
                        url: ajax.url,
                        data: {key: value},
                        async   : !isAll,// false使用同步方式执行AJAX,true使用异步方式执行ajax
                        dataType: "json",
                        success: function(data){
                            if(data.status == 'successful'){                                
                                selfVal.parent().find('.msg').addClass('ok').html(msg.ok);
                            }else if(data.status == 'failed'){
                                checkRet = false;
                                selfVal.parent().find('.msg').removeClass('ok').html(msg.error);
                            }else{
                                checkRet = false;
                            }
                            return this;
                     }
                });                 
            }               
            return this;

也许您想在表单中检查inputvalue回调ajax; 您可以查看我的网站Demo,希望对您有所帮助。 http://6yang.net/myjavascriptlib/regForm

答案 3 :(得分:1)

好吧,我的想法是制作你自己的对象,可以处理发送一系列请求,保留每个请求的历史记录,并在每个响应上做我称之为'postProccessing'的事情,这里可能是非常狡猾的一点希望能够证明我在想什么的代码。

var Ajax = function() {
    var request, callback, lst;

    if (window.XMLHttpRequest) {
        request = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        request = new ActiveXObject("Microsoft.XMLHTTP");
    }

    request.onreadystatechange = handleResponse;

    this.history = [{}];

    this.send = function(args) {
        for (var i = 0; i < args.length; i++) {
            if (args.url) {
                request.open(args.type || 'GET', args.url);
            }
            request.send(args.data || null);
            callback = args.callback;
            lst++;
        }
    }

    function handleResponse() {
        var response = {
            url: '',
            success: true,
            data: 'blah'
        };
        history.push(response);
        if (postProccess()) {
            callback();
        }

    }

    function postProcess() {
        if (this.history[lst].success) {
            return true;
        } else {
            return false;
        }
    }
}