仅在执行所有 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()
还没有完成,因此在执行某些脚本之前会刷新页面。
因此我的问题是:有没有办法只在.each
和ajax
中执行所有脚本时才刷新?
【问题讨论】:
【参考方案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脚本