0

I have nested for loop. Outer loop refer to level and inner loop refer to item.There are 2 levels and 3 items under each level. Inner loop should run ajax in order for every items. So , I had used the $.when().then().I already able to run ajax in synchronize order for each of item. But, I having problem in outer loop not wait for inner loop process the items under level 1 before proceed to level 2. I did not wait for first level to completed. It straight away process items under level 2 in synchronize order.

sql record table in sql:

uid |level |description |
____|______|____________|
  1 | 1    | a          |
  2 | 1    | b          |
  3 | 1    | c          |
  4 | 2    | a          |
  5 | 2    | b          |
  6 | 2    | c          |
____|______|____________|

Code:

<?php
include 'config.php';
$sql    ="SELECT level ,COUNT(*) AS count FROM record GROUP BY level;";
$data   =fetchall_associate($conn,$sql);

    /*
  array(2) {
  [0]=>
  array(2) {
    ["level"]=>
    string(1) "1"
    ["count"]=>
    string(1) "3"
  }
  [1]=>
  array(2) {
    ["level"]=>
    string(1) "2"
    ["count"]=>
    string(1) "3"
  }
}
    */

?>
<html>
    <head>
        <script src="external_lib/jquery_3_4_1.min.js"></script>
        <script>
        //functions
        function range(start, end) 
        {
            return Array(end - start + 1).fill().map((_, idx) => start + idx)
        }
        function get_data(data)
        {
            level_key       =0;          
            var iteration   =function()
                            {
                                 var level_p        =$.when();
                                  data.forEach(function(level_val,level_id)
                                  {
                                    item_ids    =level_val['ids'];
                                    level       =level_val['level'];  
                                    level_p         =level_p.then(function()
                                    {                                            
                                        var item_p  =$.when();
                                        item_ids.forEach(function(item_val,item_id)
                                        {                                                                             
                                          item_p    =item_p.then(function()
                                                    {    
                                                        console.log(level+'=>'+item_val);
                                                        return ajax_get_data(level,item_val);
                                                    })
                                        })
                                    })                               
                                  })
                            }        
             iteration();          
        }
        function ajax_get_data(level,item_id)
        {

            return $.ajax({
                url     :'1_circular_2.php',
                data    :{'level':level,'item_id':item_id},
                type    :'POST',
                success:function(data)
                        {
                            //console.log(level+'=>'+item_id+'=>'+data);
                        }
            });
        }
        </script>
        <script>
        $(document).ready(function()
        {
            var level_records       ='<?php echo json_encode($data);?>';
            level_records           =JSON.parse(level_records);
            c=0;
            for(i=0;i<level_records.length;i++)
            {
                level       =level_records[i]['level'];
                c           +=parseInt(level_records[i]['count']);
                start_range =(level==1)?1:(c-level_records[(i-1)]['count']+1);
                //create empty progress bar
               $('#progress_bar_container').append('<div id="level_'+level_records[i]['level']+'"></div>')
               //create array for record count
               range_array              =range(start_range,c);
               level_records[i]['ids']=range_array;
            }

            get_data(level_records);
        })
        </script>
    </head>
    <body>

        <div id="progress_bar_container">

        </div>
    </body>
</html>

console.log(level+'=>'+item_val); output:

2=>4 
2=>4 
2=>5 
2=>5 
2=>6 
2=>6

It execute level 2 before items under level one finish processed. How to solve this?

Thanks in advance.

Premlatha
  • 1,676
  • 2
  • 20
  • 40
  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Keith Mar 25 '20 at 07:18
  • @Keith, it does not answer my question. I have edited my question. I can synchronize ajax but could not make outer loop wait for inner completed before it goes next level. Outer loop:`data.forEach` and Inner loop :`item_ids.forEach` – Premlatha Mar 25 '20 at 11:10
  • `$.when().then()` does not run ajax in synchronous mode. If you did want to call ajax sync in jquery, then you would pass `async: false`. But I would strongly advice against it, as it's a deprecated feature. For solutions to your problem, read that duplicate again. Especially the bit on `async/await` as it's now 2020, not 2000.. :) – Keith Mar 25 '20 at 14:17

0 Answers0