只有在所有ajax脚本都执行完后才刷新页面

问题描述

我试图在点击按钮 child_process 时触发多个操作 我首先需要清理包含类 .button 的每个 <div> 并启动一些 ajax 脚本来更新数据库。为此,我选择 .classtoClean 结构,然后选择 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 /////
});

一切正常,但我想在 $(".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().each 中执行所有脚本时才刷新?

解决方法

将这些元素映射到请求承诺数组,以便您可以将数组传递给 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');
  });
,

尝试使用 complete 而不是成功

complete:function(response){

}

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

示例:

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

实际上很少有方法。肮脏的方式。初始化一个计数变量并保持检查,如果它变为 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