Очередь HTTP-запросов Javascript в объектной переменной - инициализация не работает

Я получил следующую реализацию очереди запросов из этого блога:

http://dsgdev.wordpress.com/2006/10/28/building-a-javascript-http-request-queue/

и хотите обернуть его объектной переменной. К сожалению, инициализация переменной внутри не работает.

Надеюсь, кто-нибудь сможет мне помочь с этим. заранее спасибо

var requestQueue = {
    inCall          : false,            // VARIABLE TO TRACK IF WE ARE CURRENTLY IN A CALL
    callToArray     : new Array(),      // QUEUE FOR CALLS
    returnToArray   : new Array(),      // QUEUE FOR FUNCTION TO EXECUTE WHEN CALL COMPLETE
    reqMethodArray  : new Array(),      // QUEUE FOR REQUEST METHOD

    createRequestObject : function(){
      var reqObj;
      var browser = navigator.appName;
      if(browser == "Microsoft Internet Explorer"){
        reqObj = new ActiveXObject("Microsoft.XMLHTTP");
        isIE = true;
      }else{
        reqObj = new XMLHttpRequest();
      }
      return reqObj;
    },

    sendCall : function(whereTo, returnTo, reqMethod){
      // GET THE NEXT ARRAY ITEM AND REMOVE FROM THE ARRAY
      this.callToArray.push(whereTo);
      this.returnToArray.push(returnTo);

      if (reqMethod != "GET" || reqMethod != "POST") { reqMethod = "GET"; }
      this.reqMethodArray.push(reqMethod);
    },

    callQueue : function(){
      // CHECK THE QUEUE AND SEND THE NEXT CALL IN LINE
      if(!this.inCall && this.callToArray.length > 0){
        // DO WE HAVE ANYTHING IN THE QUEUE?
        if(this.callToArray.length > 0){
          // WE DO, SO GET THE FIRST ITEM IN THE CALL ARRAY AND REMOVE IT
          whereTo = this.callToArray.shift();
          returnTo = this.returnToArray.shift();
          reqMethod = this.reqMethodArray.shift();
          // SEND THAT CALL
          this.doCall(whereTo, returnTo, reqMethod);
        }else{
          // UPDATE DEBUG QUEUE
        }
      }else{
        // UPDATE DEBUG QUEUE
      }
    },

    doCall : function(whereTo, returnTo){
      this.inCall = true;
      var http = this.createRequestObject();
      http.open('get', whereTo);
      // DO WE HAVE A FUNCTION TO CALL ONCE CALL IS COMPLETED?
      if(returnTo.length > 0){
        eval("http.onreadystatechange = " + returnTo);
      }
      // SEND CALL
      http.send(null);
    }
};

setInterval(requestQueue.callQueue, 100);

person dforce    schedule 20.11.2009    source источник


Ответы (1)


setInterval(requestQueue.callQueue, 100);

Снимает метод callQueue с requestQueue и передает его setInterval. Следовательно, callQueue не имеет ссылки на requestQueue; при обратном вызове this будет установлено значение window, а не requestQueue, поэтому попытка оценить this.callToArray.length вызовет ошибку.

this в JavaScript работает не так, как вы ожидаете от любого другого языка. См. этот вопрос для объяснения. Если у вас есть только один экземпляр requestQueue, вы можете просто сослаться на него вместо использования this, иначе вам нужно будет изучить привязку функции или закрытие.

Между прочим, я бы не рекомендовал использовать UA-string-sniffing для определения того, какой объект XHR использовать. Вместо этого попробуйте нюхать функции:

var r= window.XMLHttpRequest? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');

(это также будет использовать собственный XMLHttp в IE7 +, если он включен, потенциально избегая приглашения ActiveX.)

person bobince    schedule 20.11.2009