繁体   English   中英

Javascript嵌套的AJAX请求

[英]Javascript nested AJAX requests

我已经阅读了其他几个线程但似乎无法理解它。 我对Javascript并不是很了解,到目前为止基本上已经猜到了。 我有一个函数运行一个AJAX请求来从数据库中获取一些行。 然后,对于每一行,我需要运行嵌套的AJAX请求并将其值返回给第一个函数。 两个AJAX请求都独立工作,但我不知道如何正确嵌套它们。 这是我有的:

function updateSummaryVariablesInput(typeId) {
    if (typeId=='') {
        document.getElementById('summaryVariables').innerHTML='';
        return;
    }
    if (window.XMLHttpRequest) {
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp2=new XMLHttpRequest();
    } else {
        // code for IE6, IE5
        xmlhttp2=new ActiveXObject('Microsoft.XMLHTTP');
    }
    xmlhttp2.onreadystatechange=function() {
        if (xmlhttp2.readyState==4 && xmlhttp2.status==200) {
            xmlDoc=xmlhttp2.responseXML;
            txt='<table>';
            x=xmlDoc.getElementsByTagName('row');
            for (i=0;i<x.length;i++) {
                if (x[i].getElementsByTagName('common')[0].childNodes[0].nodeValue < 1) {
                    txt=txt + '<tr><th style=\"width: 150px;\">' + x[i].getElementsByTagName('label')[0].childNodes[0].nodeValue +  '</th><td>';
                    // Select
                    if (x[i].getElementsByTagName('input')[0].childNodes[0].nodeValue == 'select') {
                        txt=txt + '<select name=\"' + x[i].getElementsByTagName('title')[0].childNodes[0].nodeValue + '\"><option></option>';
                        myoptions = getSummaryVariableOptions(x[i].getElementsByTagName('id')[0].childNodes[0].nodeValue);
                        //alert(myoptions.length);
                        for (j=0;j<myoptions.length;j++) {
                            txt=txt + '<option value=\"' + myoptions[j] + '\">' + myoptions[j] + '</option>';
                        }
                        txt=txt + '</select>';
                    }
                    // Text
                    if (x[i].getElementsByTagName('input')[0].childNodes[0].nodeValue == 'text') {
                        txt=txt + '<input type=\"text\" name=\"' + x[i].getElementsByTagName('title')[0].childNodes[0].nodeValue + '\" />';
                    }
                    txt=txt + '</td></tr>';
                }
            }
            txt=txt + '</table>';
            document.getElementById('summaryVariables').innerHTML=txt;
        }
    }
    xmlhttp2.open('GET','/cgi/new/Ajax/getOutageVariablesByTypeId.php?typeId='+typeId,true);
    xmlhttp2.send();
}

function getSummaryVariableOptions(variableId) {
    var options = new Array();
    if (window.XMLHttpRequest) {
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp3=new XMLHttpRequest();
    } else {
        // code for IE6, IE5
        xmlhttp3=new ActiveXObject('Microsoft.XMLHTTP');
    }
    xmlhttp3.onreadystatechange=function() {
        if (xmlhttp3.readyState==4 && xmlhttp3.status==200) {
            xmlDoc=xmlhttp3.responseXML;
            x=xmlDoc.getElementsByTagName('row');
            for (i=0;i<x.length;i++) {
                options[i] = x[i].getElementsByTagName('description')[0].childNodes[0].nodeValue;
            }
            alert(options.length);
        }
    }
    xmlhttp3.open('GET','/cgi/new/Ajax/getOutageVariableOptionsByVariableId.php?variableId='+variableId,true);
    xmlhttp3.send();
    //alert(options.length);
    return options;
}

按原样运行,我将收到一个有效数字的警报,例如5.如果我取消注释任何其他警报功能,它们将只输出0。

问题是您正在尝试从第二个ajax调用访问返回值,就好像它是同步的一样,而不是。

因此,当您在第一个ajax调用中调用getSummaryVariableOptions时,您需要执行以下操作:

getSummaryVariableOptions(...., function (myoptions) {
  alert(myoptions.length); // now you have what you need here
  ..... /// put the reset of the code that depende on myoptions here
});

然后在getSummaryVariableOptions函数中添加一个参数, getSummaryVariableOptions函数接收数据到达时要调用的函数 - 回调。

function getSummaryVariableOptions(variableId, callback) {
    ... inside the readystate === 4 ...
    callback(options);
}

当你调用getSummaryVariableOptions它会启动ajax调用并立即返回,所以你需要等到调用完成后再调用来自调用的数据。 你不能做var myoptions = getSummaryVariableOptions(..)

编辑:

基于jquery的方法看起来像:

$.getJSON(url1, function (res1) {
  $.getJSON(url2, function (res2) {
     // now you have both res 1 and res 2 to process here...
  });
});

几乎得到了Jaime的答案。 还有一个问题,其中getSummaryVariableOptions实际上是一个异步的ajax调用,这意味着updateSummaryVariablesInput在拉入getSummaryVariableOptions的结果之前很久就完成了。这导致标记在结束标记之后附加到txt。 Shea进行了编辑,将选项标签存储在一个数组中,然后使用innerHtml将它们插入到后面。 谢谢谢谢!

var getQueue = [];

function updateSummaryVariablesInput(typeId) {
    if (typeId=='') {
        document.getElementById('summaryVariables').innerHTML='';
        return;
    }
    if (window.XMLHttpRequest) {
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp2=new XMLHttpRequest();
    } else {
        // code for IE6, IE5
        xmlhttp2=new ActiveXObject('Microsoft.XMLHTTP');
    }
    xmlhttp2.onreadystatechange=function() {
        if (xmlhttp2.readyState==4 && xmlhttp2.status==200) {
            xmlDoc=xmlhttp2.responseXML;
            txt='<table>';
            x=xmlDoc.getElementsByTagName('row');
            for (i=0;i<x.length;i++) {
                if (x[i].getElementsByTagName('common')[0].childNodes[0].nodeValue < 1) {
                    txt=txt + '<tr><th style=\"width: 150px;\">' + x[i].getElementsByTagName('label')[0].childNodes[0].nodeValue +  '</th><td>';
                    // Select
                    if (x[i].getElementsByTagName('input')[0].childNodes[0].nodeValue == 'select') {
                        txt=txt + '<select id=\"' + x[i].getElementsByTagName('id')[0].childNodes[0].nodeValue + '\" name=\"' + x[i].getElementsByTagName('title')[0].childNodes[0].nodeValue + '\"><option></option></select>';
                        // Add it to a queue, to do it later
                        getQueue.push(x[i].getElementsByTagName('id')[0].childNodes[0].nodeValue);
                    }
                    // Text
                    if (x[i].getElementsByTagName('input')[0].childNodes[0].nodeValue == 'text') {
                        txt=txt + '<input type=\"text\" name=\"' + x[i].getElementsByTagName('title')[0].childNodes[0].nodeValue + '\" />';
                    }
                    txt=txt + '</td></tr>';
                }
            }
            txt=txt + '</table>';
            document.getElementById('summaryVariables').innerHTML=txt;
            for (var gsi = 0; gsi < getQueue.length; ++gsi) {
                getSummaryVariableOptions(getQueue[gsi], function (myoptions, parentId) {
                    var parentSelect = document.getElementById(parentId),
                        optionsTxt = '';
                    for (j=0;j<myoptions.length;j++) {
                        optionsTxt=optionsTxt + '<option value=\"' + myoptions[j] + '\">' + myoptions[j] + '</option>';
                    }
                    parentSelect.innerHTML = optionsTxt;
                });
            }
        }
    }
    xmlhttp2.open('GET','/cgi/new/Ajax/getOutageVariablesByTypeId.php?typeId='+typeId,true);
    xmlhttp2.send();
}

function getSummaryVariableOptions(variableId, callback) {
    var options = new Array();
    if (window.XMLHttpRequest) {
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp3=new XMLHttpRequest();
    } else {
        // code for IE6, IE5
        xmlhttp3=new ActiveXObject('Microsoft.XMLHTTP');
    }
    xmlhttp3.onreadystatechange=function() {
        if (xmlhttp3.readyState==4 && xmlhttp3.status==200) {
            xmlDoc=xmlhttp3.responseXML;
            x=xmlDoc.getElementsByTagName('row');
            for (i=0;i<x.length;i++) {
                options[i] = x[i].getElementsByTagName('description')[0].childNodes[0].nodeValue;
            }
            // Revised to send variableId to callback
            callback(options, variableId);
            //alert(options.length);
        }
    }
    xmlhttp3.open('GET','/cgi/new/Ajax/getOutageVariableOptionsByVariableId.php?variableId='+variableId,true);
    xmlhttp3.send();
    //alert(options.length);
    //return options;
}

嵌套的ajax请求需要一个数组来存储每个请求并记录错误oncomplete ..

https://stackoverflow.com/a/18728553/2450730

一个简单的解决方案是执行顺序ajax脚本..(这是使用xhr2和JSON)还需要更多的错误检查..但它让你了解如何完成它。

var mainListArray,
Length,
Current;

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

function loadmain(){
 ajax('mainList.php',seq)
}

function seq(){
 mainListArray=JSON.parse(this.response);
 Length=mainListArray.length;
 Current=0;
 next();
}

function next(){
 ajax('Detail.php?id='+mainListArray[Current].id,add);
 Current++;
}

function add(){
 // do something with detailed data
 if(Current<Length){
  next();
 }else{
  //everything loaded.
 }
}

window.onload=loadmain;

在这种情况下,您可以避免一些ajax错误,因为每个请求在前一个请求完成后执行。

ajax功能解释

https://stackoverflow.com/a/18309057/2450730

这是顺序函数如何工作的图形示例。

http://jsfiddle.net/4eujG/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM