今天写代码,写一个很简单的删除功能,却一直莫名其妙的遇到一个关于ajax的执行顺序问题,在此写下和大家分享一下。
首先上代码。
//第一步先同步删除
layer.confirm("确认删除所选数据?",function(){
$.ajax({
type:"post",
url:url,
data:{"ids":ids},
async:false,
traditional: true,
success: function (data) {
if(data.code=="1"){
layer.msg('删除成功')
}else{
layer.msg('删除失败')
}
},
});
});
//删除完毕后再刷新表格
F5();
一段很清晰的逻辑,先用同步的ajax删除数据库里面的数据,然后再刷新页面的表格。
理想很丰满,现实却很骨感,我发现这个删除方法居然是先执行刷新,然后才弹出“确认删除所选数据”,咋回事啊!小老弟;马上想到layer.confirm这个方法是否是异步的,然后马上把layer换成了window,发现果然,layerUi里面的这个方法果然是异步,马上把代码改成这样。
layer.confirm("确认删除所选数据?",function(){
$.ajax({
type:"post",
url:"${ctx}/patrol/patrol!deleteBo.action",
data:{"ids":ids},
async:false,
traditional: true,
success: function (data) {
if(data.code=="1"){
layer.msg('删除成功')
}else{
layer.msg('删除失败')
}
},
});
//第二步的刷新
F5();
});
这次终于是先执行layer.confirm了,但是我又发现,这段代码他居然又先执行了刷新,然后才给我弹出删除成功,这又是什么情况啊,我ajax分明是同步的啊,他分明应该是要从上往下执行整个ajax的,为什么他先走的刷新呢。
我又想到,难道它的同步不同步success,难道同步的ajax只是同步到请求,那我的刷新不是只能放到success里面,但是作为一个有追求的程序员,总是不甘屈服于这种现状,我马上又想到ajax,有个参数complete,马上把代码改成如下。
layer.confirm("确认删除所选数据?",function(){
$.ajax({
type:"post",
url:"${ctx}/patrol/patrol!deleteBo.action",
data:{"ids":ids},
async:false,
traditional: true,
success: function (data) {
if(data.code=="1"){
layer.msg('删除成功')
}else{
layer.msg('删除失败')
}
},
complete: function(XMLHttpRequest, textStatus) {
//这里执行刷新
F5();
},
});
});
运行,boom,爆炸,它居然又先执行了complete里面的刷新,success都是异步的,你他妈的complete不应该和它一样嘛,不信邪的去百度查询一波,发现大家很多人的都这样说。
都是用try catch finally来类比的,就功能性而言,完全没有错,但是先后顺序完全不对啊,看来站的角度不同,看问题的思路也不一样。
又经过一番测试,我发现不管同步异步,complete方法都是先执行,它只是去请求服务器,服务器给个响应它就返回了,但success却需要去访问数据层面,然后根据数据来返回,这也侧面说明了他们的先后顺序,所以,最后我还是妥协了,把代码改成这样。
layer.confirm("确认删除所选数据?",function(){
$.ajax({
type:"post",
url:"${ctx}/patrol/patrol!deleteBo.action",
data:{"ids":ids},
async:false,
traditional: true,
success: function (data) {
if(data.code=="1"){
layer.msg('删除成功')
}else{
layer.msg('删除失败')
}
//这里刷新
F5();
},
});
});
好了,搞定,虽然是一个小问题,但是通过这一次,我更加透彻的理解了ajax中success和complete的区别,同时对它的同步异步也有了更好的理解。