5

this is a interesting problem.

i am doing an asynchronous ajax put

    return $.ajax({
        url: url,
        type: 'PUT',
        contentType: 'application/json; charset=utf-8',
        async: true, // default
        success: function (result, textStatus, xhr) {...}

this works as expected, unless a user does a put before previous call returns (even though it's async, the call does take .5 second to complete)

if a user presses the button a few times (executing multiple puts) the following happens:

  • i see only one server call in fiddler
  • success gets fired for every click
  • all callbacks get the same new row ID (returned by the server)

this leads me to inevitable conclusion that the first server callback triggers all outstanding callbacks..

i could disable the button until the callback returns, but is it possible to handle multiple outstanding calls? is this a browser limitation? best way to handle this?

UPDATE

as a test i switched to using POST instead of PUT: adjusted type: 'POST' on JS side, and [HttpPost] on web api (server side).

the behavior did not change.

UPDATE

looking at posts like this one.. this really should work. i don't see any specific reason why the rest of concurrent requests are not not making it out to the server.

Community
  • 1
  • 1
Sonic Soul
  • 23,855
  • 37
  • 130
  • 196
  • 2
    Try `cache:false` it's possible that there is caching at play and that's why you only see one response with fiddler. – Benjamin Gruenbaum Dec 03 '13 at 00:18
  • Does the browser think it's making distinct requests? – Chris Farmer Dec 03 '13 at 00:18
  • browser also sees only one put being made. i tried setting cache:false , but so far don't see any difference in above behavior. – Sonic Soul Dec 03 '13 at 00:24
  • You need to show us the whole function, why you're returning the promise, and what you do with the result, as this is not normally an issue, with neither PUT, DELETE or GET and POST. – adeneo Dec 03 '13 at 00:36
  • but i can see in fiddler that only one request is being made.. unless i wait for the fist call to finish.. then i see next request in fiddler. – Sonic Soul Dec 03 '13 at 00:45
  • You could set a flag to ignore the following click on the button while the previous progress does not finish, instead of disable it. – Lifecube Dec 03 '13 at 01:57
  • @BenjaminGruenbaum from jQuery ajax documentation: Setting cache to false will only work correctly with HEAD and GET requests. It works by appending "_={timestamp}" to the GET parameters – Sonic Soul Dec 03 '13 at 02:41

2 Answers2

1

Shouldn't PUT requests be idempotent? That is, submitting multiple requests should generate the same response? If so, the code may simply be trying to coalesce your identical PUT requests since they should all end up with the same result. If you're incrementing some ID for every post (i.e. changing server state) then you should be using POST instead of PUT.

This may not fix your issue; it's just a thought.

Jesse Bunch
  • 6,651
  • 4
  • 36
  • 59
  • HTTP/1.1 does not define how a PUT method affects the state of an origin server. There is nothing about PUT being idempotent and in fact that's usually not the case, I don't know why this was upvoted. – Benjamin Gruenbaum Dec 03 '13 at 00:23
  • @BenjaminGruenbaum see http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html section 9.1.2 – Jesse Bunch Dec 03 '13 at 00:25
  • in my case, i am using a put to create a new record. the server returns the id of the new row. is it bad practice to use put for that? – Sonic Soul Dec 03 '13 at 00:26
  • @JesseBunch The first sentence in my reply is from section 9.6 . In OP's case we don't know if the requests come in sequence or there are/might be other requests in the middle. Still, I stand corrected about the statement I've made - it wasn't phrased well now that I read it again. – Benjamin Gruenbaum Dec 03 '13 at 00:27
  • also, let me re-iterate that calling put multiple times works as expected when the calls don't overlap. – Sonic Soul Dec 03 '13 at 00:29
  • @SonicSoul I would read this for an explanation of HTTP verbs and their semantics: http://stackoverflow.com/questions/2001773/understanding-rest-verbs-error-codes-and-authentication. In this case, I would use POST since you're expecting to create a new record with every request. – Jesse Bunch Dec 03 '13 at 00:31
  • i switched to using POST but that didn't have any effect on above problem. updated my question – Sonic Soul Dec 03 '13 at 00:33
0

You can't wait for an async callback in javascript. You have to restructure your code to do all future work based on the async response from the actual callback.

If you need to make multiple consecutive ajax calls, then you issue the first one and in the success handler or response handler for the first ajax call, you issue the second ajax call and in the response handler for the second one, you carry out whatever you want to do with the data

Mr.G
  • 3,413
  • 2
  • 16
  • 20
  • hi, this is what i've observed, would like to find out what the limitation or design intent is, that's preventing me from making multiple consecutive calls – Sonic Soul Dec 09 '13 at 14:28