在允许另一个AJAX调用之前确保函数已完成

时间:2020-08-23 作者:richerimage

我正在使用ajax函数更新保存在用户元字段中的数组。

添加到数组中的值取自标记中的数据属性,这些属性也在触发时起作用,以进行ajax调用。

虽然该函数95%的时间都在工作,但无论值是否保存,都可能有点碰运气。我怀疑这是因为用户可以太快地启动这些ajax调用,而没有足够的时间让原始函数调用保存和更新元字段。

在允许该函数再次运行之前,确保ajax触发的更新元字段值的功能已完成的最佳方法是什么?

希望这是有意义的-不用说,请让我知道如果你需要任何更多的信息。

提前谢谢!!

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] => 
  )
)

2 个回复
最合适的回答,由SO网友:Eduardo Escobar 整理而成

我通常使用CSS类来控制影响特定元素的AJAX请求。通过这种方式,您可以防止在该元素上出现不需要的AJAX请求,而其他AJAX请求可能仍然会被触发,并被绑定到其他元素。

$(\'.slot\').on(\'click\', \'a.book\', function(e) {
    e.preventDefault();

    // Check if doing ajax
    if($(this).hasClass("doing-ajax")) return false;
    $(this).addClass("doing-ajax");

    var user   = $(\'#rjb_day\').attr( \'data-user\' );
    var stamp  = $(this).attr( \'data-timestamp\' );


    // console.log(bookCap);

    $(this).removeClass(\'book\').addClass(\'booked\');

    $.ajax({
        context: $(this),
        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);

           // Remove "doing-ajax" class
           $(this).removeClass("doing-ajax");
        },
        error: function(errorThrown){
            console.log(errorThrown);

            // Remove "doing-ajax" class
           $(this).removeClass("doing-ajax");
        }
    });

});
不要忘记添加context 属性设置为AJAX的config对象,正如我在上面的示例中所做的那样。

SO网友:Pradipta Sarkar

您可以使用两种方法来防止用户在完全完成ajax之前单击elem。1、显示加载程序并阻止该元素,以便在ajax完成之前,任何人都不能执行它。2.使用全局var isAjaxProcess=false;现在,在代码中创建一个条件blockIf(isAjaxProcess==false){isAjaxProcess=true:您的ajax代码在这里。并在ajax成功块中将isAjaxProcess设置为false。}

相关推荐

AJAX在返回随机帖子的CPT上加载更多

我用AJAX Load More按钮拼凑了一个帖子网格循环,用于CPT类别的帖子,但我无法使偏移量正常工作。每个页面应该有6篇文章,但目前它以随机顺序加载接下来的6篇文章,并复制其中一些。此外,我需要按钮消失时,没有更多的职位加载,我找不到如何做到这一点在任何地方!模板代码:<?php $postsPerPage = 6; $args = array( \'post_status\' => \'publish\',