使用async的Chrome和Safari ajax问题:false

我在网上到处都看到了这个,但我无法修复我的代码以避免这个问题,只是我有一个ajax函数,当我点击一些按钮时我会触发它,有时我想要一个指示器(加载动画)来显示,有时候不,所以我建立我的function:

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,该function正常工作并按预期返回数据但似乎立即调用hideIndicator()函数,我不知道如何解决这个问题。

火狐:

在此处输入图像描述

Chrome和Safari:

在此处输入图像描述

使用async: false是邪恶的。 互联网上充满了这样的post,包括Chrome和Safari在内的许多浏览器都会在发出同步AJAX请求时给出很多警告。

幸运的是,jQuery的承诺可以用来克服你的问题。 它不会改变您的函数的工作方式,也可以利用promises的强大function来生成异步请求。

您可以按如下方式修改现有函数,以便它返回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()处理程序。

希望这能解决你的问题。