Ensure function has completed before allowing another Ajax call


I am updating an array saved in a users meta field using an ajax function.

The values added to the array are taken from the data-attributes within the tags which also act at the trigger to make the ajax call.

Whilst the function works 95% of the time, it can be a bit hit and miss whether the values save or not. I suspect this is because a user can fire these ajax calls too quickly and not give enough time for the original function call to save and update the meta field.

What would be the best method to ensure the ajax triggered function of updating the meta field value has been completed before allowing the function to run again?

Hope this makes sense – needless to say, please let me know if you need any more info.

Thanks in advance!!

Sample HTML

<div id="rjb_slots" class="slots">   <h5>Mon, 24th Aug 2020</h5>   <div class="slot">     <span class="time">10:30</span>     <a class="book" data-timestamp="1598265000" href="#"></a>   </div>   <div class="slot">     <span class="time">11:00</span>     <a class="booked" data-timestamp="1598266800" href="#"></a>   </div>   <div class="slot">     <span class="time">11:30</span>     <a class="booked" data-timestamp="1598268600" href="#"></a>   </div>   <div class="slot">     <span class="time">12:00</span>     <a class="book" data-timestamp="1598270400" href="#"></a>   </div>   <div class="slot">     <span class="time">12:30</span>     <a class="booked" data-timestamp="1598272200" href="#"></a>   </div>   <div class="slot">     <span class="time">13:00</span>     <a class="book" data-timestamp="1598274000" href="#"></a>   </div>   <div class="slot">     <span class="time">19:30</span>     <a class="book" data-timestamp="1598297400" href="#"></a>   </div> </div> 

Ajax .js

$  ('.slot').on('click', 'a.book', function(e) {   e.preventDefault();    var user   = $  ('#rjb_day').attr( 'data-user' );   var stamp  = $  (this).attr( 'data-timestamp' );       // console.log(bookCap);      $  (this).removeClass('book').addClass('booked');    $  .ajax({     type: 'POST',     url: ajax_object.ajaxurl,     data: {         action: 'rjb_make_diary_slots',         user: user,         stamp: stamp     },     success: function(data) {       // This outputs the result of the ajax request       console.log(data);     },     error: function(errorThrown){         console.log(errorThrown);     }   });      }); 

Function that updates the user metafield

add_action( 'wp_ajax_rjb_make_diary_slots', 'rjb_make_diary_slots' );  function rjb_make_diary_slots() {    $  user   = $  _POST['user'];    $  stamp  = array(               array(                  'rjb_cal_day'           => strtotime('today', $  _POST['stamp']),                 'rjb_cal_when'          => $  _POST['stamp'],                 'rjb_cal_position_id'   => '',                 'rjb_cal_candidate_id'  => ''               )             );    $  calendar   = get_user_meta( $  user, 'rjb_cal', true);   $  stamps     = !empty($  calendar) ? $  calendar : array();   $  new_stamp  = array_merge($  stamps, $  stamp);    usort($  new_stamp, function($  a, $  b) {     return $  a['rjb_cal_when'] <=> $  b['rjb_cal_when'];   });    update_user_meta( $  user, 'rjb_cal', $  new_stamp);    $  log = print_r($  stamp);    wp_die($  log);  } 

Example of a value stored in the rjb_cal user meta field

array (   [0] => array (     [rjb_cal_day] => 1598227200     [rjb_cal_when] => 1598266800     [rjb_cal_position_id] =>      [rjb_cal_candidate_id] =>    )   [1] => array (     [rjb_cal_day] => 1598227200     [rjb_cal_when] => 1598268600     [rjb_cal_position_id] =>      [rjb_cal_candidate_id] =>    )   [2] => array (     [rjb_cal_day] => 1598227200     [rjb_cal_when] => 1598272200     [rjb_cal_position_id] =>      [rjb_cal_candidate_id] =>    ) )