jQuery AJAX solution inside each() loop

后端 未结 3 1816
暖寄归人
暖寄归人 2020-12-07 06:41

I have noticed that I\'m having problems when I\'m using AJAX in jQuery inside a .each() loop. Only the first record in my database are being updated when the script execute

相关标签:
3条回答
  • 2020-12-07 06:57

    There are a couple things happening here.

    1. By re-using the request variable in the loop (scoped outside the loop), every iteration of the loop assigns a new object to request, overwriting what was there. This means you are only setting the response handlers for the last iteration.

    2. Your request.done method reloads the page, which in practice will halt the other requests and...

    3. You are looking up the same userTypeId for each iteration of the loop, as mentioned by @Sean

    0 讨论(0)
  • 2020-12-07 07:02

    jQuery's $.ajax() returns a jQuery XMLHttpRequest Object (a "jqXHR"). You are storing this object into your "response" variable.

    Your problem is scope. You are storing all N of your jqXHRs into the same "request" variable. By the end of your loop, "request" is only pointing to the last jqXHR, and thus .done() will only be called when your LAST request completes.

    As Karl Anderson pointed out, you should store ALL of your jqXHRs into an array, and then execute a single callback once ALL of them have [asynchronously] completed.

    var XHRs = [];
    
    // ...
    
    $("tr.recUserType").each(function() {
        $this = $(this);
        _userTypeId = $this.find("#userTypeId").html();
        _userTypeName = $this.find("#userTypeName").val();
        _isDeleted = $this.find("#isDeleted").val();
    
        XHRs.push($.ajax({
            url: "save.php",
            type: "POST",
            data: {userTypeId: _userTypeId, userTypeName: _userTypeName, isDeleted: _isDeleted}
        }));
    });
    
    $.when(XHRs).then(function() {
        document.location.reload();
    });
    

    Also, avoid the delicious temptation to use $.ajax()'s "async: false". The browser will be forced to hang until a request completes, which is bad. You can pretty much always accomplish a $.ajax() call asynchronously; it may require some craftiness, but will definitely be for the better.

    0 讨论(0)
  • 2020-12-07 07:02

    Your issue is in this block of code:

    request.done(function(){
        document.location.reload();
    });
    

    Since the actions are asynchronous, this line is being executed before the save is completing, thus after the first save does complete, it executes the done logic.

    You need to create an array of deferred objects that you can then wait until they are all executed before proceeding forward with your logic using the jQuery .when()/.then() functions.

    Here is a previous StackOverflow question that details how to setup this situation. Please read the accepted answer of jQuery when each is completede trigger function.

    0 讨论(0)
提交回复
热议问题