我在网上到处都看到了这个,但我无法修复我的代码以避免这个问题,只是我有一个ajax函数,当我点击一些按钮时触发,有时我想要一个指示器(加载动画)到显示,有时不是,所以我建立我的功能:
function doAjax(action, todo, items, error_num, hide_indicator) {
items.action = action;
items.do = todo;
var postedObj;
$.ajax({
type: 'post',
dataType: 'html',
url: ajaxURL,
data: items,
async: false,
beforeSend: function() {
if (!hide_indicator) showIndicator();
},
success: function(data) {
if (data) {
ajaxObj = JSON.parse(data);
if (ajaxObj.ok) {
postedObj = ajaxObj;
} else {
alert(ajaxObj.error);
postedObj = false;
}
} else {
alert('[' + error_num + '] Something went wrong.');
postedObj = false;
}
if (!hide_indicator) hideIndicator();
},
error: function() {
alert('[' + error_num + '] Something went wrong.');
postedObj = false;
if (!hide_indicator) hideIndicator();
}
});
return postedObj;
}
以下是我在按钮上执行的操作:
$(document).on('click', '.ad-single', function() {
var addataObj = doAjax('post_requests', 'get-ad-info', {"id": $(this).data('ad')}, '158', false); // false means DON'T hide the indicator
if (addataObj) {
loadContent(addataObj.ad);
}
});
好了,现在,一切都按预期在Firefox上运行,当我点击我的按钮时,指示器显示并等待ajax返回数据,然后再次隐藏指示器。
这在Chrome和Safari上不起作用,该功能正常工作并按预期返回数据但似乎立即调用hideIndicator()
函数,我不知道如何解决这个问题。
火狐:
Chrome和Safari:
答案 0 :(得分:3)
使用async: false
是邪恶的。互联网上充满了这样的帖子,包括Chrome和Safari在内的许多浏览器都会在发出同步AJAX请求时给出很多警告。
幸运的是,jQuery的承诺可以用来克服你的问题。它不会改变你的函数的工作方式,也会利用promises的功能来发出异步请求。
您可以按如下方式修改现有函数,以便它返回AJAX承诺,而不是结果。
function doAjax(action, todo, items, error_num, hide_indicator) {
items.action = action;
items.do = todo;
return $.ajax({
type: 'post',
dataType: 'html',
url: ajaxURL,
data: items,
beforeSend: function() {
if (!hide_indicator) showIndicator();
}
})
.then(function(data) {
if (!hide_indicator) {
hideIndicator();
}
if (data) {
ajaxObj = JSON.parse(data);
if (ajaxObj.ok) {
return ajaxObj;
}
alert(ajaxObj.error);
return false;
}
alert('[' + error_num + '] Something went wrong.');
return false;
}, function() {
if (!hide_indicator) {
hideIndicator();
}
alert('[' + error_num + '] Something went wrong.');
return false;
});
}
这里,.then
函数可用于预处理响应,并将适当的值返回给后续的promise处理程序。
后续的promise处理程序可以如下实现,它调用doAjax
函数,并通过预处理对值返回作出反应。
$(document).on('click', '.ad-single', function() {
doAjax('post_requests', 'get-ad-info', {"id": $(this).data('ad')}, '158', false)
.then(function(addataObj) {
if (addataObj) {
loadContent(addataObj.ad);
}
});
});
此处,.then()
与之前的.then()
相关联,并对返回的值做出反应(在addataObj
中收到)。请注意,它只对AJAX调用的成功做出反应。如果您还想处理错误响应,则需要将第二个参数作为函数传递给.then()
处理程序。
希望这能解决你的问题。