从javascript多次调用ajax

时间:2013-12-27 13:22:38

标签: javascript ajax

for(var x=0 ; x<=23 ; x++)
{
    AjaxRequest16 = null;
    AjaxRequest16 = getXmlHttpRequestObject(); // method here to load the request

    if(AjaxRequest16.readyState == 4 || AjaxRequest16.readyState == 0) 
    {
        AjaxRequest16.open("GET", "ajax.php?id=16&AreaID=" +encodeURIComponent(AreaID)+ "&month=" 
                +encodeURIComponent(document.getElementById("cboMonths").value)+ "&TimeSlot=" +encodeURIComponent(x), true);

        AjaxRequest16.send(null);

        AjaxRequest16.onreadystatechange = function()
        {
            if(AjaxRequest16.readyState == 4) 
            {
                var innerHTML = AjaxRequest16.responseText.toString();
                /* Retrieve data from the server and display. */ 
                document.getElementById("divTime"+x).innerHTML = innerHTML;

            }/* end if */            
        }/* end function */            
    }/* end if */            

}/* end if */  

我试图多次调用ajax来加载一组div中的数据:其中24个,它们以divTime0,divTime1,divTime2,divTime3 ...... divTime23开头。每次调用它时,TimeSlot的值对应于例如div。 TimeSlot = 0进入divTime0。

我知道这里的ajax调用是相互覆盖的,但不知道如何解决它而不写出24块代码来使它工作。注:如果我在没有for循环的情况下单独执行,那么 正在工作,但它只会填充24个div中的1个

以下代码用于加载带有图像的24个div:

for(var x=0 ; x<=23 ; x++)
    document.getElementById("timeanalysisimg"+x).src="ajax.php?id=15&AreaID=" +encodeURIComponent(AreaID); 

我正在尝试做类似的事情,而不必编写不必要的代码。有什么想法吗?

我搞定了。刚刚粘贴解决方案

for(var x=0 ; x<=9 ; x++)
{
    test(x, AreaID); // calling the function which resides externally to the loop
}

外部方法:

function test(x, AreaID)
{
        var AjaxRequest16 = null;
        AjaxRequest16 = getXmlHttpRequestObject();

        if(AjaxRequest16.readyState == 4 || AjaxRequest16.readyState == 0) 
        {
            AjaxRequest16.open("GET", "ajax.php?id=16&AreaID=" +encodeURIComponent(AreaID)+ "&month=" 
                    +encodeURIComponent(document.getElementById("cboMonths").value)+ "&TimeSlot=" +encodeURIComponent(x), true);

            AjaxRequest16.send(null);

            AjaxRequest16.onreadystatechange = function()
            {
                if(AjaxRequest16.readyState == 4) 
                {
                    var innerHTML = AjaxRequest16.responseText.toString();
                    /* Retrieve data from the server and display. */ 
                    document.getElementById("divTime"+x).innerHTML = innerHTML;

                }      
            }
        }    
}

6 个答案:

答案 0 :(得分:1)

你可以这样做:

for(var x=0 ; x<=23 ; x++)
{
    req(x);

}

function req(x){
    var AjaxRequest16 = null;
    AjaxRequest16 = getXmlHttpRequestObject(); // method here to load the request

    if(AjaxRequest16.readyState == 4 || AjaxRequest16.readyState == 0) 
    {
        AjaxRequest16.open("GET", "ajax.php?id=16&AreaID=" +encodeURIComponent(AreaID)+ "&month=" 
                +encodeURIComponent(document.getElementById("cboMonths").value)+ "&TimeSlot=" +encodeURIComponent(x), true);

        AjaxRequest16.send(null);

        AjaxRequest16.onreadystatechange = function()
        {
            if(AjaxRequest16.readyState == 4) 
            {
                var innerHTML = AjaxRequest16.responseText.toString();
                /* Retrieve data from the server and display. */ 
                document.getElementById("divTime"+x).innerHTML = innerHTML;

            }/* end if */            
        }/* end function */            
    }/* end if */            

}

答案 1 :(得分:1)

将块放入函数中:

for(var x=0 ; x<=23 ; x++)
{
  (function(x) {
    var AjaxRequest16 = getXmlHttpRequestObject();
    //rest of the code

  }(x));
} //end of for loop

答案 2 :(得分:1)

我更改了所有代码,但它完全符合您的要求,而不使用asynchronous = false和浏览器冻结:

function ajaxRequest(url, callback) {
    var req = null;
    if (window.XMLHttpRequest) req = new XMLHttpRequest();
    else if (window.ActiveXObject) // if IE
    {
        try {
            req = new ActiveXObject("Msxml2.XMLHTTP")
        } catch (e) {
            try {
                req = new ActiveXObject("Microsoft.XMLHTTP")
            } catch (e) {}
        }
    } else {
        throw ("No Ajax support!");
        return;
    }
    req.open('GET', url, true);
    req.onreadystatechange = function () {
        if (req.readyState == 4) {
            if (typeof (callback) == "function") callback(req);
        }
    };
    req.send(null);
    return req;
}

function loadMyData() {
    var x = parseInt(arguments[0]);
    if (x > 23) {
        alert("all 24 is loaded!");
    }
    var url = "ajax.php?id=16&AreaID=" + encodeURIComponent(AreaID) +
        "&month=" + encodeURIComponent(document.getElementById("cboMonths").value) +
        "&TimeSlot=" + encodeURIComponent(x);
    var callback = Function('req', 'document.getElementById("divTime' + x + '").innerHTML =' +
        ' req.responseText;' +
        'loadMyData(' + x + ');');
    ajaxRequest(url, callback);
}

loadMyData(0);

答案 3 :(得分:0)

你应该进行ajax调用asenkron false试试这个:

for(var x=0 ; x<=23 ; x++)
    {
        AjaxRequest16 = null;
        AjaxRequest16 = getXmlHttpRequestObject(); // method here to load the request

        if(AjaxRequest16.readyState == 4 || AjaxRequest16.readyState == 0) 
        {
            AjaxRequest16.open("GET", "ajax.php?id=16&AreaID=" +encodeURIComponent(AreaID)+ "&month=" 
                    +encodeURIComponent(document.getElementById("cboMonths").value)+ "&TimeSlot=" +encodeURIComponent(x), false);

            AjaxRequest16.send(null);

            AjaxRequest16.onreadystatechange = function()
            {
                if(AjaxRequest16.readyState == 4) 
                {
                    var innerHTML = AjaxRequest16.responseText.toString();
                    /* Retrieve data from the server and display. */ 
                    document.getElementById("divTime"+x).innerHTML = innerHTML;

                }/* end if */            
            }/* end function */            
        }/* end if */            

    }/* end if */  

答案 4 :(得分:0)

使用ajax

按顺序加载内容

这是一个简单的现代浏览器的ajax函数(chrome,safari,ie10,android,ios)

function ajax(a,b,c){//url,function,just a placeholder
 c=new XMLHttpRequest;
 c.open('GET',a);
 c.onload=b;
 c.send()
}

这就是你按顺序加载内容的方法

var current=0,
    x=23;

function handler(){
 document.getElementById("divTime"+current).innerHTML=this.response;
 current++
 if(current<x){
  ajax('url.php?id='+current,handler)
 }
}

ajax('url.php?id='+current,handler);

这样你就不会覆盖以前的ajax调用。


多个同时进行的ajax调用是一个糟糕的解决方案。

无论如何要在创建多个ajax请求函数的同时实现多个ajax调用。

 var ajaxcall=[];

 ajaxcall[0]=new XMLHttpRequest;
 ajaxcall[0].CUSTOMID=0;
 ajaxcall[0].open('GET','url.php?id='+0);
 ajaxcall[0].onload=function(){console.log(this.CUSTOMID,this.response)};
 ajaxcall[0].send();

答案 5 :(得分:0)

归结为Ajax调用的异步性质。 在请求结束(完成或失败)之前,每个Ajax上下文必须保持活动状态。

在初始代码中,您只使用一个Ajax请求上下文。循环启动第一个请求,但在第一个请求处理之前很久就用第二个请求覆盖它的上下文。当服务器响应时(几毫秒之后),浏览器端没有处理响应的处理程序(第24个除外)。

您的解决方法是为每个请求创建不同的上下文和回调,因为您的全局函数将它们存储在不同的闭包中。

但是,结果你将同时在服务器上发出24个Ajax请求,如果你的PHP脚本不希望在同一个请求上同时执行,这可能会导致不必要的开销,甚至崩溃。此外,在完成这些请求时同步代码并不容易。

以下是我用于自己应用的内容:

// --------------------------------------------------------------------
// Ajax lite
// --------------------------------------------------------------------
function PageCache (target, void_contents)
{
    this.text = {};
    this.req  = {};
    this.void_contents = void_contents || 'void';
    this.target = target;
}

PageCache.prototype = {
    // synchronous load
    load: function (page)
    {
        if (!this.text[page]) this.text[page] = this._launch_request (page); 
        return this.text[page]; 
    },

    // asynchronous load
    fetch: function (page, action)
    {
        if (this.text[page])
        {
            action (this, page);
            return;
        }
        if (this.req[page]) return;
        this.req[page] = this._launch_request (page, 
            function(_this, _page, _action) {
                return function(){ 
                    _this._loader(_page,_action);
                    };
            }(this,page,action)); 
    },

    _launch_request: function (page, callback)
    {
        var req;
        try {
                req = window.XMLHttpRequest
                    ? new XMLHttpRequest()
                    : new ActiveXObject("Microsoft.XMLHTTP");
            }
        catch (e) {}
        req.open('GET', this.target.replace (/\$/, page), callback!=undefined);
        if (callback) req.onreadystatechange = callback;
        req.send(null);
        return callback ? req : this._get_result (req);
    },

    _get_result: function (req)
    {
        return (req.status < 400)
                ? req.responseText
                : this.void_contents;
    },

    _loader: function (page, action)
    {
        if (!this.req[page] || (this.req[page].readyState != 4)) return;
        this.text[page] = this._get_result (this.req[page])
        delete this.req[page];
        if (action) action (this.text[page], page);
    }
}

在您的示例中,您可以像这样使用它:

首先,进行一些清理:

function compute_id (AreaID,x) {
return "id=16&AreaID=" 
      + encodeURIComponent(AreaID)
      + "&month=" 
      + encodeURIComponent(document.getElementById("cboMonths").value)
      + "&TimeSlot="
      + x; // I suspect all the encodeURIComponent() calls are unnecessary
}

var Ajax = new PageCache (
     'ajax.php?$',          // '$' will be replaced with fetch() parameter
     'error loading data'); // contents in case of request failure

1)同时请求(不推荐)

for (var x = 0; x != 24 ; x++) {
    // store current x value in a closure
    var request_done = function (_x) {
        return function (responseText) {
            document.getElementById("divTime"+_x).innerHTML = responseText;
            }}(x);
    }
    Ajax.fetch (compute_id (AreaID,x), request_done);          
}

2)顺序阻塞请求(非常糟糕,除非您的代码无法在没有数据的情况下继续执行,否则不要这样做)

for (var x = 0; x != 24 ; x++) {
    document.getElementById("divTime"+x).innerHTML = 
        Ajax.load (compute_id (AreaID,x));          
}

3)顺序非阻塞请求

var AjaxCtx = { x:0, max:24};

// launch first request
Ajax.fetch (compute_id (AreaID, AjaxCtx.x), request_done);

function request_done (responseText) {
    document.getElementById("divTime"+AjaxCtx.x).innerHTML = responseText;

    // request completion triggers the next
    if (++AjaxCtx.x != AjaxCtx.max)
        Ajax.fetch (compute_id (AreaID,AjaxCtx.x), request_done);
}