Why is multiple ajax query loop running success twice?

前端 未结 1 1232
误落风尘
误落风尘 2021-01-28 07:03

So everything works, the problem is if conflicts are found it calls showInstConflicts(allconflicts, joined); twice... Debugging shows it evaluates true twice but I

相关标签:
1条回答
  • 2021-01-28 07:19

    So, it looks like JSONTable is an Ajax call. That means it's asynchronous. As such, your for loop will immediately launch all the async calls and the index i will be at the value at the end of the loop when the first one finishes. Plus your Ajax calls may finish in any random order.

    If you want to see the correct value of i that corresponds to that specific Ajax call, then you'd have to put i into a closure so it is preserved uniquely for each Ajax call.

    If you want your Ajax calls to be executed in strict sequential order, then you will have to restructure how you run them (you can't use a straight for loop).

    Here's how you would preserve the value of i for each separate ajax call:

    var times = joined.length;
    var nodata = 0;
    var allconflicts = $('<div></div>');
    
    for (var i = 0; i < times; i++) {
        // create closure to capture the value of i
        (function(i) {
            var conflicts = $('<div></div>').appendTo(allconflicts);
            //use $.JSONTable plugin (see plugins.js) to check instructor conflicts
            conflicts.JSONTable({
                url: '/ajax/ajaxCSFInstCheck.php',
                options: joined[i],
                noWraps: ['allrows'],
                columns: ['Name', 'Primary', 'Responsible', 'CRN', 'Class', 'Dates', 'Days', 'Times', 'Location', 'XST', 'Web', 'All Meetings'],
                responsive: true,
                success: function () {
                    //if conflicts found, show on the final ajax return
                    //*** this is evaluating true twice per run ***
                    if (i == times && nodata < times) {
                        showInstConflicts(allconflicts, joined);
                    }
                },
                nodata: function () {
                    //if no conflicts found, make the PDF
                    nodata++;
                    if (i == times && nodata == times) {
                        generatePDF();
                    }
                }
            });
        })(i);
    }
    

    I'm having a hard time following how exactly you're trying to process all this data. Generally, if you're retrieving N pieces of async data and some operations you want to do on this data needs to look at more than one async result, then the simplest approach is to collect all the data (usually into an array) and then process all the results at once at the end when you have all the data. Then, any inter-result dependencies can be looked at once.

    When doing this with multiple ajax calls, it is generally simplest to use promises and let the promises infrastructure collect all the results and deliver it to your callback in an array when all the ajax calls are done (probably using Promise.all()).

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