10

I got problems with the async nature of Javascript / JQuery.

Lets say the following (no latency is counted for, in order to not make it so troublesome);

I got three buttons (A, B, C) on a page, each of the buttons adds an item into a shopping cart with one ajax-request each. If I put an intentional delay of 5 seconds in the serverside script (PHP) and pushes the buttons with 1 second apart, I want the result to be the following:

Request A, 5 seconds
Request B, 6 seconds
Request C, 7 seconds

However, the result is like this

Request A, 5 seconds
Request B, 10 seconds
Request C, 15 seconds

This have to mean that the requests are queued and not run simultaneously, right? Isnt this opposite to what async is? I also tried to add a random get-parameter to the url in order to force some uniqueness to the request, no luck though.

I did read a little about this. If you avoid using the same "request object (?)" this problem wont occure. Is it possible to force this behaviour in JQuery?

This is the code that I am using

 $.ajax(
 {
  url   : strAjaxUrl + '?random=' + Math.floor(Math.random()*9999999999),
  data  : 'ajax=add-to-cart&product=' + product,
  type  : 'GET',
  success  : function(responseData)
  {
   // update ui
  },
  error  : function(responseData)
  {
   // show error
  }
 });

I also tried both GET and POST, no difference.

I want the requests to be sent right when the button is clicked, not when the previous request is finnished. I want the requests to be run simultaneously, not in a queue.

Jeremy
  • 1
  • 85
  • 340
  • 366
Emil
  • 1,035
  • 3
  • 10
  • 19

5 Answers5

8

Ok here is what I would try, I think you need a better way to log the time. I am not sure what you are doing now to test the times but here is a good way.

Get Firebug for Firefox if you haven't already done so.

Open Firebug and go to the net tab. Make sure you enable it.

As you click each button you should see each request coming in. If you click each button, you don't see the next request starting until the previous request has ended then this tells me there is something wrong in javascript. However, I am guessing you should the beginning of each bar to be 1 second apart. Do this and let us know what you see.

Edit

I think I found you problem. I am guessing you are using sleep function in php. The sleep function sleeps for the current session. If you open up 3 tabs, and put the ajax url, you will notice the same behavior. 5, 10, then 15s for each tab to finish. I tried googling and found the same results with other people. This is probably because PHP is not really multithreaded. I suggest using a different framework.

Amir Raminfar
  • 33,777
  • 7
  • 93
  • 123
3

Apparently this behaviour is very easily passable by using session_write_close(); in PHP. However, this opens up for DDos attacks with ease. I refreshed a page by holding down F5 in 10 seconds and killed my developmen computer in no-time.

Case closed.

Emil
  • 1,035
  • 3
  • 10
  • 19
  • Emil I spent a lot of time and found you a solution. But you wrote the same answer and accepted it as correct. You could have given credit to some community members instead of your self. – Amir Raminfar Jan 24 '11 at 00:36
  • Done, sorry dude. And thank you Amir for the help! I really appreciate it! :) – Emil Jan 24 '11 at 09:08
0

From what I understand Parallel ajax calls can be done only if you're not in different scope of js. Seems that being in different same js scope makes you using the same 'request object' in a serialize way.

So we can find on Stack overflow two excellent response on this at the page linked, see the second response with a parallel query stack object, this is the thing you need, add your requests on this parallele stack and they will really get fired in parallel (Stack overflow is the best site in the web :-) ). Parallel asynchronous Ajax requests using jQuery

Community
  • 1
  • 1
regilero
  • 29,806
  • 6
  • 60
  • 99
  • The code shown in the other thread is code for a loop and ajax-calls in the loop, right? I want to make one ajax-call on each event that will run "beside each other" without colliding – Emil Jan 13 '11 at 13:25
  • the first response is with a loop, the second example provides an object handling the query queue, in your case using this object should fit your needs, you'll maybe need to use jQuery.data to store the queue of queries in a way independant of js scope. – regilero Jan 13 '11 at 13:31
  • You are still missunderstanding. I want to do the following. Click button A, send an ajax request that takes 5 seconds. 1 second after the first click I click button B and sends an ajax request that takes 5 seconds. After the second click I click button C and sends an ajax request that takes 5 seconds. These are supposed to be fun in parralell with B 1 second after A and C 1 second after B. The are not to be sent all at once. Look here: http://data.fuskbugg.se/dipdip/_net.png – Emil Jan 13 '11 at 13:40
  • At least you have with ParallelAjaxExecuter the base of your object. You need to add some functionnalities on it. he can run the query in parallele, first point, then you want to get the results in the same order as what you ask him, so this object should queue the results as welland unlock them when the previous one is finished (but you may have some quite complex code to hanlde failures). – regilero Jan 13 '11 at 14:19
  • Here it's not a waiting queue, it's a work queue, used to give some tasks to ParallelAjaxExecutor, he will not wait until the end of the request to take the next item in the work queue and run it. The queue is used to send your orders ton an external object handling the ajax requests in one central point – regilero Jan 13 '11 at 15:01
0

There is a limit on the number of concurrent Ajax requests. See this

How many concurrent AJAX (XmlHttpRequest) requests are allowed in popular browsers?

Looks like it is browser dependent.

Bob

Community
  • 1
  • 1
rcravens
  • 8,320
  • 2
  • 33
  • 26
0

you cant do it simultaneously, cause JS have fake async operations due to one browser UI thread. But you can try Web Workers, the way to execute code outsude of the browser UI thread. They already supported in Firefox 3.5, Chrome 3, and Safari 4. Maybe it will improve your application usability

Madman
  • 3,171
  • 2
  • 32
  • 44