仅在执行所有 ajax 脚本时刷新页面

Posted

技术标签:

【中文标题】仅在执行所有 ajax 脚本时刷新页面【英文标题】:refresh a page only when all the ajax scripts are executed 【发布时间】:2021-09-15 03:33:05 【问题描述】:

单击按钮.button 时,我试图触发几个动作 我首先需要清理每个包含.classToClean 类的<div> 并启动一些ajax 脚本来更新数据库。为此,我选择 $(.classToClean).each(function(index)); 结构,然后选择 ajax $.ajax() 结构。到目前为止,我的代码如下所示。

$(".button").on("click", function () 
  ///// each loop /////
  $( ".classToClean" ).each(function( index ) 
    $.ajax(
      //... (clean 1)
      success:function(response)
        $.ajax(
          //... (clean 2)
          success:function(response)
          
        );
      
    );
  );
  ///// /each loop /////
);

一旦干净,我想将新语句写入数据库,但这次我只需要 ajax。结果我得到了这样的结果:

$(".button").on("click", function () 
      ///// each loop /////
      $( ".classToClean" ).each(function( index ) 
        $.ajax(
          //... (clean 1)
          success:function(response)
            $.ajax(
              //... (clean 2)
              success:function(response)
              
            );
          
        );
      );
      ///// /each loop /////
      $.ajax(
        //... (write 1)
        success:function(response)
          $.ajax(
            //... (write 2)
            success:function(response)
            
          );
        
      );
    );

一切正常,但我想在 each()ajax 完成后刷新。通常我只有一个脚本,所以我添加了一个这样的成功函数

success:function(response)
  location.href = "...";
,

但是因为我有很多脚本要运行,所以似乎没有好地方放它。例如,如果我将它放在"write 2" 成功函数中,有时似乎.each() 还没有完成,因此在执行某些脚本之前会刷新页面。 因此我的问题是:有没有办法只在.eachajax 中执行所有脚本时才刷新?

【问题讨论】:

【参考方案1】:

将这些元素映射到请求承诺数组,以便您可以将数组传递给 Promise.all();

请注意,success 不是承诺链的一部分,因此您需要 then()

在每个外部 $.ajax.then() 中返回 #2 ajax 承诺也继续构建承诺链

类似:

const cleanRequests = $('.classToClean').map(function (index, element) 
    // return clean 1 to array
    return  $.ajax( /*clean 1 options*/).then(function (clean1_response) 
      // return clean2 promise
      return $.ajax( /*clean 2 options*/ ).then(function (clean2Response) 
        // not sure what you want returned
      );
    );
  ).get();

Promise.all(cleanRequests).then(function (allCleanResults) 
    // all the clean requests are done, do the write stuff
    return $.ajax(/*write 1 options*/).then(function (write1_response) 
      return $.ajax( /*write 2 options*/ ).then(function (write2Response) 
        // not sure what you want returned
      );
    );
  )
  .then(function () 
    /// all done, reload page
  )
  .catch(function (err) 
    console.log('Oooops something went wrong');
  );

【讨论】:

我不返回任何值,只是与数据库交互。我正在尝试了解 Promise.all 和 map() 文档.. Promise.all() 在传递给它的数组中的所有承诺都已解决后解决。 map() 用于从可迭代集合中返回一个数组【参考方案2】:

尝试使用完成而不是成功

complete:function(response)


实际上,如果您只需要用更新的数据库替换 div,则不需要刷新和清理。只需使用 replaceWith() 替换您的 div 或整个页面或 html() 以防您只想替换几个元素而不是整个页面

示例:

$(".button").on("click", function () 
  $.ajax
  ....
  complete:function(response)
   updatedDiv = "your div html code";
   $(#yourdiv).replaceWith(updatedDiv);
   
  );

【讨论】:

【参考方案3】:

实际上很少有方法。肮脏的方式。初始化一个计数变量并保持检查,如果它变为0,则刷新。

var c = 0;
var f = None;
$(".button").on("click", function () 
      f = 1;
      ///// each loop /////
      c +=1;
      $( ".classToClean" ).each(function( index ) 
        $.ajax(
          //... (clean 1)
          success:function(response)
            $.ajax(
              //... (clean 2)
              success:function(response)
                 c -=1;
              
            );
          
        );
      );
      ///// /each loop /////
      c +=1 ;
      $.ajax(
        //... (write 1)
        success:function(response)
          $.ajax(
            //... (write 2)
            success:function(response)
               c -= 1;
            
          );
        
      );
    );
    while (true) 
       if (c == 0 && f != None) 
          break;
          //refresh here
       
     
);

添加了一个更脏的方法来避免这种 while 循环首先运行并提前刷新。我希望问题海报更喜欢使用@charlietfl 的答案或使用如下所示的下划线方法

Goodway:使用下划线 after https://underscorejs.org/#after

【讨论】:

while 将在发出请求之前运行 在您的肮脏示例中,我们同意第一个 c +=1;应该在循环内。我知道它很脏,但至少它是合乎逻辑且易于理解的。我会测试一下。 @charlietfl 这是我关心的问题之一。 非常感谢我喜欢这个主意 =) !

以上是关于仅在执行所有 ajax 脚本时刷新页面的主要内容,如果未能解决你的问题,请参考以下文章

Yii: 如何在CGridView通过Ajax方式刷新数据后执行JS脚本

页面仅在第一次通过 jquery 在 mvc 中刷新 ajax 调用响应

DataTables 仅在页面刷新时加载

React JS 仅在我刷新页面时读取道具数据

Rails 页面仅在刷新后应用

ajax执行action,怎么没有刷新页面数据,要自己刷新一下页面数据才出来?