jqueryeachsequential

jquery: Is there a way to run "each" iterations sequentially?


I have a table to manipulate. It contains rows from my database (in descending order). I want to be able to use an array of ids, and remove the matching rows from the table. As I remove each one, I make another call to the database to retrieve the 'next' row to show so I can append it to the table. I have tried this two different ways - searching for the last row in the table after the append, and having my "get the next row" return the ID of the row that was found.

No matter which tactic I use, the "new" last id is the same, so if I have 2 elements in my array, the same row is appended 2 times. I think I'm being burned because essentially both of my ajax calls are run at the same time.

So basically, I want each iteration of the "each()" to run sequentially. Is there a way to do that?

// get the last one in the table so we can use it for getting a replacement row
var last_sync_queue_id = enclosing_table.find('tr').last().find('input[type=checkbox]').val();

for( const idx in rows_reset )
{
    var row_that_was_reset = rows_reset[idx];

    enclosing_table.find('input[type="checkbox"]').each( function() {
        var checkbox = $(this);

        if (checkbox.val() == row_that_was_reset )
        {
            // remove the row from the table
            checkbox.closest("tr").remove();

            // and get another one to append to the end of the table
            console.log("finding 'next' row, using " + last_sync_queue_id);
            $.post( "/AjaxControlPanel/get_one_more_error_row", {'before_row': last_sync_queue_id}, function(data) {
                if ( data.success && data.html )
                {
                    enclosing_table.append(data.html);

                    // using a returned value from the "next row" function
                    last_sync_queue_id = data.new_last_sync_queue_id;
                    //
                    // OR
                    //
                    // trying to find the "new" last row in the table and getting the id from that
                    last_sync_queue_id = enclosing_table.find('tr').last().find('input[type=checkbox]').val();

                    console.log("New Last id: " + last_sync_queue_id);
                }
            });

            return false;
        }
    });
}

Solution

  • To make your loop sequential you could use async/await, so your whole logic should be inside async function. Here we use an async IIFE:

    (async () => {
    
        // get the last one in the table so we can use it for getting a replacement row
        const last_sync_queue_id = enclosing_table.find('tr').last().find('input[type=checkbox]').val();
    
        for (const idx in rows_reset) {
    
            const row_that_was_reset = rows_reset[idx];
            const checkboxes = enclosing_table.find('input[type="checkbox"]');
    
            for (let i = 0; i < checkboxes.length; i++) {
    
                const checkbox = $(checkboxes[i]);
    
                if (checkbox.val() == row_that_was_reset) {
    
                    // remove the row from the table
                    checkbox.closest("tr").remove();
    
                    // and get another one to append to the end of the table
                    console.log("finding 'next' row, using " + last_sync_queue_id);
    
                    const data = await $.post("/AjaxControlPanel/get_one_more_error_row", { 'before_row': last_sync_queue_id });
    
                    if (data.success && data.html) {
                        enclosing_table.append(data.html);
    
                        // using a returned value from the "next row" function
                        last_sync_queue_id = data.new_last_sync_queue_id;
                        //
                        // OR
                        //
                        // trying to find the "new" last row in the table and getting the id from that
                        last_sync_queue_id = enclosing_table.find('tr').last().find('input[type=checkbox]').val();
    
                        console.log("New Last id: " + last_sync_queue_id);
                    }
    
                    break;
                }
            }
        }
    
    })();