sayedsohail Posted August 4, 2007 Share Posted August 4, 2007 Hi everyone, below is the ajax function i am using to communicate with the backend server, it works fine, but i got a small issue, i wish to send three request in my onload event, here sometimes one of the ajax request ending up without executing. Than, i tried sending the request using settimeout, which works fine on my local server, but this is not going to be idle since on the internet, i can't set a predictable timeout, if i use longer delay using setimeout than the users would hate. if i use shorter delays than i am not sure if the is going to work. Is there any way i could improve this function to execute the requests one after the other. this what i thought of adding before calling MyHttpRequest(), if (MyHttpRequest.readyState !=0) { MyHttpRequest.abort(); } , but this simple abort the previous request. Here is the code: MyHttpRequest.open("get", url_encode(file + query_string), true); // handle the httprequest MyHttpRequest.onreadystatechange = function () { if(MyHttpRequest.readyState == 4) // done and responded { document.getElementById(target_div).innerHTML = MyHttpRequest.responseText; // display result } else { document.getElementById(target_div).innerHTML = MyHttpLoading; // still working } } MyHttpRequest.send(null); } else { document.getElementById(target_div).innerHTML = ErrorMSG; // the browser was unable to create a httprequest } } // end of "AJAX" function Quote Link to comment Share on other sites More sharing options...
sayedsohail Posted August 6, 2007 Author Share Posted August 6, 2007 At last i am close to somewhere and would like to share with viewers, but can someone help to improve this function a bit as it needs some tweekening. Setting up initial variables: // TURN ON DEBUG WINDOW FEEDBACK // I WILL WANT TO DISABLE THIS IN THE LIVE VERSION… var httpTesting = true; // SET MY REQUEST OBJECT var http = createRequestObject(); // VARIABLE TO TRACK IF WE ARE CURRENTLY IN A CALL var inCall = false; // QUEUE FOR CALLS var callToArray = new Array(); // QUEUE FOR FUNCTION TO EXECUTE WHEN CALL COMPLETE var returnToArray = new Array(); Create our Request Object: function createRequestObject() { var reqObj; var browser = navigator.appName; if(browser == "Microsoft Internet Explorer"){ reqObj = new ActiveXObject("Microsoft.XMLHTTP"); isIE = true; }else{ reqObj = new XMLHttpRequest(); } return reqObj; } Insert calls to the Queue: function sendCall(whereTo, returnTo){ // GET THE NEXT ARRAY ITEM AND REMOVE FROM THE ARRAY callToArray.push(whereTo); returnToArray.push(returnTo); } Watcher function that is called on intervals to set out queued calls based on inCall variable: function callQueue(){ // IF WE HAVE A WAY OF MONITORING THE QUEUE, UPDATE IT if(httpTesting){ calls = ""; for(i=0;i<callToArray.length;i++){ calls += callToArray[i] + "n"; } document.getElementsByName("queueTest")[0].value = calls; document.getElementsByName("queueInCall")[0].value = inCall; document.getElementsByName("queueReadyState")[0].value = http.readyState; } // CHECK THE QUEUE AND SEND THE NEXT CALL IN LINE if(!inCall && callToArray.length > 0){ // DO WE HAVE ANYTHING IN THE QUEUE? if(callToArray.length > 0){ // WE DO, SO GET THE FIRST ITEM IN THE CALL ARRAY AND REMOVE IT whereTo = callToArray.shift(); returnTo = returnToArray.shift(); // SEND THAT CALL doCall(whereTo, returnTo); }else{ // UPDATE DEBUG QUEUE if(httpTesting){ document.getElementsByName("queueMsg")[0].value = "no items in queue."; } } }else{ // UPDATE DEBUG QUEUE if(httpTesting){ if(inCall){ document.getElementsByName("queueMsg")[0].value = "currently in a call."; }else{ document.getElementsByName("queueMsg")[0].value = "no items in queue."; } } } } If we are not currently in a call and have a pending request, the call URL is sent here: function doCall(whereTo, returnTo){ inCall = true; 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); } This is a generic return function intended to just clear the inCall variable when we have a call type that we don’t need/expect a response from: function hr_inCall(){ if(http.readyState == 4){ inCall = false; } } And finally, to start the Queue engine, we have: var queueWatcher = setInterval(callQueue, 100); Finally, for any page that needs to make a call, for example, a log in, I would just have the submit button call a function that gathers the data and sends it to the queue, as such: function checkLogin(){ username = document.getElementsByName("loginEmail")[0].value; password = document.getElementsByName("loginPassword")[0].value; document.getElementById("loginSubmit").innerHTML = "Checking Login..."; sendCall("req/getLogin.php?username=" + username + "&password=" + password, "hr_checkLogin"); } You will notice when I sendCall, I have “hr_checkLogin” as the second parameter, which, once the call is complete, will call: function hr_checkLogin(){ if(http.readyState == 4){ inCall = false; response = http.responseText if(response != "0"){ document.getElementById("loginArea").innerHTML = "Login successful. Welcome back. <A href='projects.php'>Projects</a>"; }else{ document.getElementById("loginSubmit").innerHTML = "<font color='red'>Login Failed</font>"; } } } } The solution to this problem would be to use an array and push each request in it. Then use a timer to frequently look at this array, shift one request of the bottom and execute it. Repeat until the array is empty... Quote Link to comment Share on other sites More sharing options...
sayedsohail Posted August 6, 2007 Author Share Posted August 6, 2007 the topic moved under ajax queue requests. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.