www.webdeveloper.com
Results 1 to 14 of 14

Thread: triggering functions in series

Hybrid View

  1. #1
    Join Date
    Jul 2010
    Location
    Birmingham, UK
    Posts
    67

    triggering functions in series

    I have a written a couple of ajax functions that run when a page is loaded to pre-fill certain form elements and text, however I have run into a problem with them in terms of the way they load/display. Because I am using the same function severel times, the scripts sometimes seem to stop or not load properly and move on to the next instance. To get around this I have used "setTimeout" for each instance to give it time to execute before moving on to the next instance, and to a certain extent this works. However, sometimes it still skips an instance, usually the first, even with ridiculously long times upwards of one second.

    I have a rough example of the code here:

    Code:
    function loadForm(){
      //staggered times to load properly
      var loadOne = setTimeout(function () 
         {getMessage();}, 50);
      var loadTwo = setTimeout(function () 
         {getMessage();}, 150);
      var loadThree = setTimeout(function () 
         {getMessage();}, 250);
      }
    My question is this: is there a way to check that an instance has completed fully before moving on to the next without having to provide any arbitrary delay times?

  2. #2
    Join Date
    Dec 2005
    Posts
    2,984
    Code:
    ajaxreq.onreadystatechange = function() {
       //response received, call your next function here
    }
    I've switched careers...
    I'm NO LONGER a scientist,
    but now a web developer...
    awesome.

  3. #3
    Join Date
    Jul 2010
    Location
    Birmingham, UK
    Posts
    67
    thanks aj_nsc, but my problem with that approach is that onreadystatechange is built into that function already - where i get back my xml response. i could see that working if i wasn't using the same function over and over or feeding in a bunch of other information.

    it might make sense to write a new function that collects all of my info in one go and writes it into one huge xml string, but it would be more useful to have one generic function that can be used on different pages instead of similar functions tailored to each specific page.

  4. #4
    Join Date
    Dec 2005
    Posts
    2,984
    [/code]
    var responseOneLoaded = false;
    var responseTwoLoaded = false;
    var responseThreeLoaded = false;

    function getResponseOne() {

    responseOne.onreadystatechange = function() {
    responseOneLoaded = true;
    }

    }


    function getResponseTwo() {
    if(!responseOneLoaded) {
    setTimeout(function() { getResponseTwo(); },1000);
    return;
    }

    //get responseTwo
    responseTwo.onreadystatechange = function() {
    responseTwoLoaded = true;
    }
    }

    function getResponseThree() {
    if(!responseTwoLoaded) {
    setTimeout(function() { getResponseThree(); },1000);
    return;
    }
    }


    getResponseOne();
    getResponseTwo();
    getResponseThree();
    [code]

    You could always use flags, like in the above. For the record I don't advocate using that could specifically - it's pretty messy - but you get the idea of what a flag is. There's a ton more ways to do it, and I wouldn't necessary choose this one, I'd probably stick with the theory behind what I said in my first reply. You seem to understand what I'm driving at, rather than being a copy/paster, so sit back and think about other ways how you make my first example work, just with different syntax, because that's probably the method I'd go with.
    I've switched careers...
    I'm NO LONGER a scientist,
    but now a web developer...
    awesome.

  5. #5
    Join Date
    Dec 2010
    Location
    Newton Aycliffe, Co Durham, England
    Posts
    72
    Mimewear. I had this problem and agonised for ages over it. The only way I could solve it was this way. (I have pasted a real-life example.)

    function basket(){
    var ff = new Boolean(false);
    var mv = new Boolean(false);
    if (window.XMLHttpRequest)
    {
    xmlhttp_basket=new XMLHttpRequest();
    var ff = new Boolean(true);
    }
    else
    {
    xmlhttp_basket=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp_basket.onreadystatechange=function()
    {
    if (xmlhttp_basket.readyState==4 && xmlhttp_basket.status==200)
    {
    //2***********
    var mv = new Boolean(true);
    if(mv=true)
    {
    if (ff=true)
    {
    xmlhttp_basket_tot=new XMLHttpRequest();
    }
    else
    {
    xmlhttp_basket_tot=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp_basket_tot.onreadystatechange=function()
    {
    if (xmlhttp_basket_tot.readyState==4 && xmlhttp_basket_tot.status==200)
    {
    document.getElementById("ordertotal").innerHTML=xmlhttp_basket_tot.responseText;
    document.getElementById("ordertotal").style.backgroundColor='#000000';
    document.getElementById("ordertotal").style.borderStyle='solid';
    document.getElementById("ordertotal").style.borderColor='#FFFFFF';
    document.getElementById("ordertotal").style.borderWidth='2px';
    }
    }
    xmlhttp_basket_tot.open("GET","basket_total.php" ,true);
    xmlhttp_basket_tot.send();
    }
    //2***********

    document.getElementById("order").style.backgroundColor='#000000';
    document.getElementById("order").style.borderStyle='solid';
    document.getElementById("order").style.borderColor='#FFFFFF';
    document.getElementById("order").style.borderWidth='2px';
    document.getElementById("order").innerHTML=xmlhttp_basket.responseText;
    }
    }
    xmlhttp_basket.open("GET","basket.php" ,true);
    xmlhttp_basket.send();
    }

    It's obviously for a shopping cart. Hope it helps

  6. #6
    Join Date
    Jul 2010
    Location
    Birmingham, UK
    Posts
    67

    Angry

    Thanks to both of you, but I'm going to throw in the towel for now and just go with the stupidly long setTimeout intervals, otherwise I could spend the rest of the weekend or longer trying to fix this.

    I tried creating a global variable within the "getMessage" function using the "window.variable" approach, and then changing this variable after onreadystatechange for each pass at the function. The problem remained the same in that the functions still seemed to be triggering too rapidly, and so they randomly triggered or not - some would work on one page load, and then not work on the next page refresh.

    When I have time I will rewrite it all to get my info on one pass and so avoid having to load a bunch of functions all at once, though I am still wondering how it is possible that there is not simple "execute this function, and then..." type of method. Seems like that would be useful.

  7. #7
    Join Date
    Jul 2008
    Location
    urbana, il
    Posts
    2,787
    change the nature of your updates so that they can be applied in any order.
    i would also chaeck your ajax function to make sure you are getting new XMLHTTPREQUEST objects each time; clobbering an old one would break the functionality if it were mid-transfer or waiting on a response.

  8. #8
    Join Date
    Jul 2010
    Location
    Birmingham, UK
    Posts
    67

    resolved

    Thanks rnd_me, that worked like magic. I basically created a handful of requests and plugged them into my getMessage function. So:

    Code:
    var one = getXMLHTTPRequest();
    var two = getXMLHTTPRequest();
    var three = getXMLHTTPRequest();
    
    function loadForm(){
      var loadOne = getMessage('task1', one);
      var loadTwo = getMessage('task2', two);
      var loadThree = getMessage('task3', three);
      }
    Each instance loads with it's given task and its respective request, and there is no need to place a delay between each process. Cool. That saves me a lot of needless code, etc.

  9. #9
    Join Date
    Dec 2010
    Location
    Newton Aycliffe, Co Durham, England
    Posts
    72
    Mimewear. I know that my solution repeats a lot of code, but here's why: If each request doesn't have a seperate 'identity', you have no control over the sequence of the return of the responses.

    Consider this. I have a site that updates a piece of text every five seconds. It scrolls randomly through a php recordset and displays the result of the query. User inputs trigger other requests at the same time and can be any time. I literally saw the wrong div with the wrong text show for five seconds.

    I thought about making the browser selection into a function, but anything related to each call had to be unique.

    I'd be interested to see if you can reduce the code because it is a pain. I put a lot of effort in, but didn't figure it out.

  10. #10
    Join Date
    Dec 2003
    Location
    Bucharest, ROMANIA
    Posts
    15,428
    Gledders, you might use a synchronous request:
    Code:
    xmlhttp_basket.open("GET","basket.php" ,false);
    If so, the user will not be able to perform his requests whenever he wants, but only after any of those 5 seconds auto requests is ready and the response utilized.

  11. #11
    Join Date
    Dec 2010
    Location
    Newton Aycliffe, Co Durham, England
    Posts
    72
    I looked at that. What I couldn't explain was that the correct text appeared in the wrong div.

    This was my understanding (possibly flawed,) that if for example, request a) is made slightly before request b), but request b) takes less processing time at the server, the function can not distinguish for which request it is receiving the response unless the request is manually identified. Otherwise the function simply processes responses in the sequence it receives them? It simply detects a ready-state change and processes the response.

    I understood the asynchronous part of AJAX to be the key to the process, for example the way Google Maps processes large graphics in the background whilst the user is doing something else. To be fair, for my purposes, I'm not processing such huge amounts of data in the background so synchronous request wouldn't make much difference, but synchronous requests sort of spoil the theory.

    Now I'm still learning about all of this, so I'm only responding here to learn and correct any mis-understandings I have (I will not be the only one). Please don't rush to reply unless the boss is at lunch or you are the boss!

  12. #12
    Join Date
    Jul 2008
    Location
    urbana, il
    Posts
    2,787
    Quote Originally Posted by Gledders View Post

    This was my understanding (possibly flawed,) that if for example, request a) is made slightly before request b), but request b) takes less processing time at the server, the function can not distinguish for which request it is receiving the response unless the request is manually identified. Otherwise the function simply processes responses in the sequence it receives them? It simply detects a ready-state change and processes the response.
    yes and no. while there isn't a uri on responseText, i belive xml docs have a uri property of some sort that identifies the source.
    regardless, async ajax takes a function and functions can store values via closure, so it all depends on how you use your callback.

    here is a simple ajax function that passes three args to the callback, in order of most-to-least used: responseText, the whole xmlHttpRequestObject, and the url making the request:


    Code:
    function aGet(turl, callback) {
    	var XHRt =  !window.XMLHttpRequest ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest();
    	XHRt.onreadystatechange = function () {if (XHRt.readyState == 4 && XHRt.status == 200) {callback(XHRt.responseText, XHRt, turl);}};
    	XHRt.open("GET", turl, true);
    	XHRt.setRequestHeader("Content-Type", "text/html");
    	XHRt.send("");
    	return XHRt;
    }
    
    
    
    aGet("/forum/", function(txt, xml, url){
     alert( url );
    });
    aGet("http://webdeveloper.com/forum/newreply.php?do=newreply&p=1156285", function(txt, xml, url){
     alert( url );
    });
    in the above code, sometimes the main page is first, sometimes the thread view page is first, but they always both work and are identifiable.
    Last edited by rnd me; 05-23-2011 at 12:21 PM.

  13. #13
    Join Date
    Dec 2003
    Location
    Bucharest, ROMANIA
    Posts
    15,428
    The problem with asynchronous requests is that, even if you send them in a certain order, but in a quick sequence, the responses will arrive in a random order, depending on the connection (merely) speed. So, as rnd me said, it is important to mark and identify the pairs request/response. Nice idea, rnd me.
    Last edited by Kor; 05-23-2011 at 12:53 PM.

  14. #14
    Join Date
    Jul 2010
    Location
    Birmingham, UK
    Posts
    67
    In the case of my page, what I am doing is validating a user's form input as they fill each field and displaying a message indicating success or a specific error message. What I wanted to make sure of is that if the user reloads the page or goes back that these messages under each field match up with prior responses.

    So my ajax requests are broken up into two groups: one on page load that checks all the fields and displays one of three generic messages, and another set that is specific to each field and is only triggered as the user makes changes. For the second group I have a basic set of functions that all use the same xmlhttprequest because the timing is not really an issue. The first group, however, uses a different request for each field because they are all firing off at the same time.

    You can check it out here: www.wordchute.com/register. (It's not entirely finished, but you will get the idea.)

    I had a similar problem elsewhere on the site, except in this case the function involved updating various information every few seconds using setInterval, so it sounds somewhat similar to what you were doing Gledders. In this case I just spit all of my information into one big xml output using one request, and then sent it on its way using the different div id's to fill in the updated content. If I needed different intervals though or wanted to break it up into more managable chunks, I would follow rnd_me's advice and use a different xmlhttprequest for each task.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles