views:

252

answers:

2

I want to make asychronous get requests and to take different results based on the input that I provide to each one. Here is my code:

param=1;
$.get('http://localhost/my_page_1.php', param, function(data) {
   alert("id = "+param);
   $('.resul   5.t').html(data);
});

param=2;
$.get('http://localhost/my_page_2.php', param, function(data) {
   alert("id = "+param);
   $('.result').html(data);
});

The result for both requests is: "id = 2" I want the results to be: "id = 1" for the 1st request, and "id = 2" for the second one..

I want to do this for many requests in one HTML file and integrate the results into the HTML as soon as they are ready.

Can anyone help me to solve this problem?

thank you in advance, Thanasis

+3  A: 

Because your calls are asynchronous, the callbacks do not execute until all of the above lines have already run. This means param will be set to the value 2 before your first get request resolves.

Create unique names for your variables like param1, param2, instead of just reassigning param.

Edit:

Check out this code:

    for (var i = 0 ; i < 3; i++) {
        param = i;
        $.get('http://www.google.com',genCallback(param));
        param = i+5;
    }

    function genCallback(param) {
        var cb = function (data) {
            alert(param);
        }
        return cb;
    }

Honestly, I'm not really sure how it works. You'll notice it alerts the number 0, 1, 2 in some order, even though I'm constantly changing param. Instead of creating an anonymous function in the get directly, I create a function based on the parameter. What I think happens is a closure is created over cb which includes the local param of genCallback at the time it executes.

Fletcher Moore
Yes, this works, thank you.. But I want to do that with tens of requests in a loop. I try to do it in a loop but it doesn't work. And I want all the requests to be asynchronous, so as my program hasn't to hang up for each response time.. Other ideas?
Thanasis Petsas
An array is a good idea if you know all the requests you are going to make ahead of time. I have edited my answer with a more flexible solution.
Fletcher Moore
Nice solution, I'm kind of mad at myself for not figuring it out myself and kind of happy since I will be able to sleep tonight ;) Read about how it works [here](http://en.wikipedia.org/wiki/Closure_%28computer_science%29)
Simen Echholt
@Simen Were you thinking about this for the last hour as well? I thought closures might work, but I wasn't sure until I made a test case.
Fletcher Moore
Yes i was, while reading to my upcoming exam, eventually dropping the reading and focusing on the problem until a solution came up. Now back to the books!
Simen Echholt
This is such a brilliant idea Fletcher! I tried it and it works really fine with what I wanted to do at first. Now, I have to adjust my code to this programming model you proposed. Thank you all for the help! A last detail with which I am a little bit confused: In your code Fletcher you do a GET request targeting the google.com domain. By default browsers prevent the cross-domain requests. So, your code would worked with this URL if you did the request through a proxy as described here: http://developer.yahoo.com/javascript/howto-proxy.html, right?
Thanasis Petsas
I'm not sure how cross-domain blocking works. It seems like the request is still made and a result is sent back, but the browser itself discards the response. If you have Live Headers in Firefox, look at the request to Google made by my script here: http://fletchermoore.me/test/. My script code is at http://fletchermoore.me/test/test.js. I'll post the response header in my answer.
Fletcher Moore
And yes, your request would work if you did it through a proxy because the browser isn't making the request; your server is making the request. And servers are allowed to do whatever they want.
Fletcher Moore
Using Wireshark I determined the entire response from google is sent, but it seems to be the case the browser discards it and gives me an empty string instead.
Fletcher Moore
+1  A: 

When you call an AJAX function, the callback of that request is handled out of synch with the rest of your code. The function specified to be called when the request is finished isn't called before... the request is finished.

This is how your code most often (due to the asynchronous nature of AJAX) would work:

  1. You set param = 1 and send the first ajax request
  2. You set param = 2 and send the second ajax request
  3. First get call is finished. The callback for this call is processed. Your param variable is now 2
  4. Second get call is finished. The callback for this call is processed. Your param variable still 2

The solution would be to have different variables for each call or to increment param and send the second ajax call inside the callback function of the first one.

Simen Echholt
Thank you, I understand now what's happening! Fletcher Moore's solution is working, but I want to make all of my requests in a loop so as each one of them to be asynchronous and for each one there is provided a different output! Is this feasible to be implemented something like that? A solution that I can imagine is to pre-compute all of these values and store them in an array, and then make a loop and create each request with the corresponding array element.. Any other suggestions?
Thanasis Petsas