1

I have two ajax call that cannot be done in one call. When the first ajax call starts the second ajax call can start immediately or whenever the user presses a send button. If the second ajax call starts he has to wait for the response of the first ajax call because he needs data from it.

How can I achieve that the second ajax call sends his request only after the first ajax call's response has been arrived?

  • Is there another way than setTimeout?
  • Can I register a listener for ajax call 2 on ajax call 1 somehow?

My code would be:

var xhrUploadComplete = false;

// ajax call 1
$.ajax({
url: url,
type: "POST",
data: formdata,
processData: false,
contentType: false,
complete: function(response) {
    var returnedResponse = JSON.parse(response.responseText);
    xhrUploadComplete = true;
}
});

// ajax call 2
if (xhrUploadComplete) {
  $.ajax({
  url: url2,
  type: "POST",
  data: formdata2,
  processData: false,
  contentType: false,
  complete: function(response) {
    ...
  }
  });
}

Edit: The second ajax call cannot be posted in done() or complete() of the first call, because it depends on the users choice to send the final form. The purpose of this two step process is to send an image to the server just after the user had inserted it to an input type=file.

Edit: In know that I cannot the the if(..) because this is an async call. I wrote it to make clear what I need to do. I think I need something like a future in Java.

4

1 回答 1

6

xhrUploadComplete will be set to true asynchronously (in the future, when the request has finished) so your if-condition (that is evaluated right after the request is started) will never be fulfilled. You cannot simply return (or set) a value from an ajax call. Instead, move the code that waits for the results into the handler that would have set/returned the variable:

$.ajax({
    url: url,
    type: "POST",
    data: formdata,
    processData: false,
    contentType: false,
    complete: function(response) {
        var returnedResponse = JSON.parse(response.responseText);
        $.ajax({
            url: url2,
            type: "POST",
            data: formdata2,
            processData: false,
            contentType: false,
            complete: function(response) {
                …
            }
        });
    }
});

With the Promise pattern you can compose those even more elegantly:

$.ajax({
    url: url,
    type: "POST",
    data: formdata,
    processData: false,
    contentType: false
}).then(function(response) {
    var returnedResponse = JSON.parse(response.responseText);
    return $.ajax({
        url: url2,
        type: "POST",
        data: formdata2,
        processData: false,
        contentType: false
    });
}).done(function(response) {
    // result of the last request
    …
}, function(error) {
   // either of them failed
});

Maybe you need also need this:

var ajax1 = $.ajax({
    url: url, …
}).then(function(response) {
    return JSON.parse(response.responseText);
});
$(user).on("decision", function(e) { // whatever :-)
    // as soon as ajax1 will be or has already finished
    ajax1.then(function(response1) {
        // schedule ajax2
        return $.ajax({
             url: url2, …
        })
    }).done(function(response) {
        // result of the last request
        …
    }, function(error) {
        // either of them failed
    });
});
于 2013-10-01T20:53:44.587 回答