learnMedlem sedan jan. 20051 130 inlägg Jag har en JS-funktion som utför 2 AJAX-"anrop".
// Funktion
function myFunction() {
ajaxHttp('funktion1.php?test=1', 'objekt1');
ajaxHttp('funktion2.php?test=2', 'objekt2');
}
var httpAjax = false;
var object;
// Ajax
function ajaxHttp (url, object) {
objectid = object;
httpAjax = false;
handler = false;
if (window.XMLHttpRequest) {
httpAjax = new XMLHttpRequest();
if (httpAjax.overrideMimeType) {
httpAjax.overrideMimeType('text/xml');
}
} else if (window.ActiveXObject) {
try {
httpAjax = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
httpAjax = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
alert("Couldn´t build an AJAX instance.");
return false;
}
}
}
try {
httpAjax.onreadystatechange = getPage;
} catch (e) {
alert("onreadystatechange didn´t go well!");
return false;
}
try {
httpAjax.open('GET', url, true);
} catch (e) {
alert("Couldn´t open url.");
return false;
}
try {
httpAjax.send(null);
} catch (e) {
alert("Couldn´t send request.");
return false;
}
return true;
}
// Här händer det
function getPage () {
document.getElementById(object).style.display = 'block';
if (httpAjax.readyState == 4) {
document.getElementById(object).innerHTML = httpAjax.responseText;
return true;
} else {
document.getElementById(object).innerHTML = "<img src=\"loading.gif\" />";
}
}
Mitt problem är nu att det första "anropet" (ajaxHttp('funktion1.php?test=1', 'objekt1')) inte hinner färdigt innan det andra körs. loading.gif visas och försvinner inte i object1. Hur gör jag för att det ska vänta till sin tur?
Förmodligen väldigt enkelt, förmodligen något som ska in mellan " ajaxHttp('funktion1.php?test=1', 'objekt1')" och "ajaxHttp('funktion2.php?test=2', 'objekt2')", men jag vet inte vad... Hjälp? :bire
learnMedlem sedan jan. 20051 130 inlägg Någon som vet hur man skapar denna fördröjning i javascript? Måste ju gå att åstadkomma, eller?!
I detta fall är nog det enklaste att ändra denna rad genom att ändra true till false. Det gör att anropet blir synkront istället för asynkront, alltså att det väntar till requesten blir klar.
httpAjax.open('GET', url, false);
yadorMedlem sedan mars 2004455 inlägg Kan du inte lägga till en extra variabel och om den är true så vänta. T.ex
x = false;
function()
{
while(!x){ }
x = true;
//.....
x = false;
}
Eller det kanske inte går?
learnMedlem sedan jan. 20051 130 inlägg nitro2k01: Då funkar det inte alls... Inget händer.
yador: Hmm, hur menar du?
yadorMedlem sedan mars 2004455 inlägg Menade såhär:
// Funktion
function myFunction() {
ajaxHttp('funktion1.php?test=1', 'objekt1');
ajaxHttp('funktion2.php?test=2', 'objekt2');
}
var httpAjax = false;
var object;
run = false;
// Ajax
function ajaxHttp (url, object) {
while(run){ }
run = true;
objectid = object;
httpAjax = false;
handler = false;
if (window.XMLHttpRequest) {
httpAjax = new XMLHttpRequest();
if (httpAjax.overrideMimeType) {
httpAjax.overrideMimeType('text/xml');
}
} else if (window.ActiveXObject) {
try {
httpAjax = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
httpAjax = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
alert("Couldn´t build an AJAX instance.");
return false;
}
}
}
try {
httpAjax.onreadystatechange = getPage;
} catch (e) {
alert("onreadystatechange didn´t go well!");
return false;
}
try {
httpAjax.open('GET', url, true);
} catch (e) {
alert("Couldn´t open url.");
return false;
}
try {
httpAjax.send(null);
} catch (e) {
alert("Couldn´t send request.");
return false;
}
run = false;
return true;
}
// Här händer det
function getPage () {
document.getElementById(object).style.display = 'block';
if (httpAjax.readyState == 4) {
document.getElementById(object).innerHTML = httpAjax.responseText;
return true;
} else {
document.getElementById(object).innerHTML = "<img src=\"loading.gif\" />";
}
}
Men nu när jag tänker efter så tror jag att det inte fungerar, men men.
learnMedlem sedan jan. 20051 130 inlägg jo, det verkar funka, men känns som en riktig fullösning... ;)
Någon annan som har tips på hur man kan lösa detta. Borde ju finnas ett allmän lösning på detta i javascript tycker jag!
R: Funkade inte!
learnMedlem sedan jan. 20051 130 inlägg Ett sätt är ju förstås att dublera all kod så det blir två uppsättningar av AJAX-funktionen och sedan skriva:
// Funktion
function myFunction() {
ajaxHttp('funktion1.php?test=1', 'objekt1');
ajaxHttp[B][blue]2[/blue][/B]('funktion2.php?test=2', 'objekt2');
}
(Se 2:an i andra "anropet".)
Men det känns ju väldigt omständigt och fel. Det måste ju finnas något sätt att göra så att funktionen väntar på att föregående rad laddats färdigt...???
SPiNMedlem sedan mars 20007 896 inlägg Sätt en timeout på den andra funktionen, kanske. I myFunction():
ajaxHttp('...
setTimeout('ajaxHttp("funktion2.php?test=2")', 200);
learnMedlem sedan jan. 20051 130 inlägg Hmm, hur vet jag hur lång tid det tar för den första att laddas klart. Känns inte helt rätt... :l
oGGoMedlem sedan apr. 2003120 inlägg Nej nej nej, sätt för bövelen inte timeout eller liknande, det är riktiga fullösningar. Problemet i ditt fall är att httpAjax är satt som ett globalt objekt (den ligger utanför din metod). Detta innebär att båda dina anrop använder sig av samma objekt för ajax-anropen och således blir det inte bra.
Jag har gjort några smärre modifikationer på din kod:
Den första är alltså att jag lyft in dina två objekt:
httpAjax
& object
samt att jag tog bort funktionen getPage() och stoppade in dess logik direkt i din ajaxHttp funktion
// Funktion
function myFunction()
{
ajaxHttp('funktion1.php?test=1', 'objekt1');
ajaxHttp('funktion2.php?test=2', 'objekt2');
}
// Ajax
function ajaxHttp (url, object)
{
var httpAjax;
var object;
document.getElementById(object).innerHTML = "<img src=\"loading.gif\" />";
if (window.XMLHttpRequest)
{
httpAjax = new XMLHttpRequest();
if (httpAjax.overrideMimeType)
httpAjax.overrideMimeType('text/xml');
}
else if (window.ActiveXObject)
{
try
{
httpAjax = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
httpAjax = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
alert("Couldn´t build an AJAX instance.");
}
}
}
try
{
httpAjax.onreadystatechange = function()
{
if (httpAjax.readyState == 4 /*LOADED*/)
{
if (httpAjax.status == 200 /*OK*/)
{
document.getElementById(object).style.display = 'block';
document.getElementById(object).innerHTML = httpAjax.responseText;
}
}
}
}
catch (e)
{
alert("onreadystatechange didn´t go well!");
}
try
{
httpAjax.open('GET', url, true);
}
catch (e)
{
alert("Couldn´t open url.");
}
try
{
httpAjax.send(null);
}
catch (e)
{
alert("Couldn´t send request.");
}
}
learnMedlem sedan jan. 20051 130 inlägg Hej!
Nej, det fungerar inte heller. Precis samma sak som innan, det andra anropet "väntar" inte på att det första är färdigt!
Någon??
En grej skulle väl vara om functionen returnerade true om den laddats färdigt, så skulle man kunna:
if(ajaxHttp('funktion1.php?test=1', 'objekt1')) {
ajaxHttp('funktion2.php?test=2', 'objekt2');
}
Men sen är jag ju ingen hejjare på ajax ...
I detta fall bör i alla fall anrop två ske först när anrop 1 gett true.
Ska den vänta på det andra anropet så istället för att mecka med loopar som ligger och väntar så skippa det här med att göra anropet asynkront.
Ungefär så här:
// Funktion
function myFunction()
{
ajaxHttp('funktion1.php?test=1', 'objekt1');
ajaxHttp('funktion2.php?test=2', 'objekt2');
}
// Ajax
function ajaxHttp (url, object)
{
document.getElementById(object).innerHTML = "<img src=\"loading.gif\" />";
var response = fetchXhrResponse(url);
if (response)
{
document.getElementById(object).style.display = 'block';
document.getElementById(object).innerHTML = response;
}
}
function fetchXhrResponse(url)
{
var httpAjax = getXhrObject();
if (!httpAjax)
return null;
try
{
httpAjax.open('GET', url, false);
}
catch (e)
{
alert("Couldn´t open url.");
return null;
}
try
{
httpAjax.send(null);
}
catch (e)
{
alert("Couldn´t send request.");
return null;
}
if (httpAjax.status == 200 /*OK*/)
{
return httpAjax.responseText;
}
else
{
return null;
}
}
function getXhrObject()
{
var httpAjax = null;
if (window.XMLHttpRequest)
{
httpAjax = new XMLHttpRequest();
if (httpAjax.overrideMimeType)
httpAjax.overrideMimeType('text/xml');
}
else if (window.ActiveXObject)
{
try
{
httpAjax = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
httpAjax = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
alert("Couldn´t build an AJAX instance.");
}
}
}
return httpAjax;
}
effataMedlem sedan apr. 2008137 inlägg Rimligtvis behöver du lägga anrop som ska köras efter varandra i en stack som sen kollas vid callback.
Alternativt löser alla de stora js-libbarna detta utmärkt med eventhantering.
Exempel med mootools:
var myAjax = new Request({method: 'get', url: 'http://site.com/requestHandler.php'});
myAjax.addEvent('success', function() {
//kod för anrop två här
});
myAjax.send("objekt1");
learnMedlem sedan jan. 20051 130 inlägg Men på något (enklare) sätt måste det väl gå att köra två ajax-anrop efter varandra? Ingen som vet? Ge mig hemskt gärna ett exempel eller ändra lite i min kod ovan. Tack!!
Låt din callback för anrop ett starta anrop två.
learnMedlem sedan jan. 20051 130 inlägg Det kan ju vara en variant förstås, ska kolla på det. Tack för tipset.