我已经阅读了其他几个主题,但似乎无法理解它。我对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.
答案 0 :(得分:1)
问题在于您尝试从第二个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
函数添加一个参数,该函数接收数据到达时要调用的函数 - 回调。
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...
});
});
答案 1 :(得分:1)
几乎得到了Jaime的答案。还有一个问题,其中getSummaryVariableOptions实际上是一个异步的ajax调用,这意味着updateSummaryVariablesInput在拉入getSummaryVariableOptions的结果之前很久就完成了。这导致标记在结束标记之后附加到txt。 Shea进行了编辑,将选项标签存储在一个数组中,然后使用innerHtml将它们插入到后面。谢谢Shea!
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;
}
答案 2 :(得分:0)
嵌套的ajax请求需要一个数组来存储每个请求并记录错误oncomplete ..
https://stackoverflow.com/a/18728553/2450730
一个简单的解决方案是执行顺序ajax脚本..(这是使用xhr2&amp; 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
以下是顺序函数如何工作的图形示例。