大家下午好 -
有没有一种众所周知的方法来检查 $.ajax
调用是否已完成?
-- 例如 --
假设我正在使用 $.ajax
调用从 .geojson 文件加载大量传单多边形(作为图层组异步加载)。在正常情况下,这几乎会立即发生 - 但用户这次选择加载大型作业。用户假设多边形集已加载,并尝试过早地对这组图层执行某些操作 - 却发现什么也没有发生(该图层组实际上在浏览器中还不存在)。
我的直觉(我是网络开发新手)是为要检查的依赖算法设置某种全局标志。我们将在加载图层之前设置该标志,然后在 $.ajax
调用的 .done({})
部分将其更改为其他值。
--更新--
我重新设计了代码,允许用户选择是否要重试请求,并强制浏览器在重试请求之前等待一段时间。
但是,我还发现问题似乎出在 Chrome 上。 Firefox 似乎能够在 $.ajax.always 回调完成后立即对其进行处理(换句话说,$.ajax.always 回调将中断 javascript 的常规流程)。
Chrome 似乎阻止了 $.ajax.always 回调,并且仅在所有其他 javascript 完成运行后才允许其执行(无中断)。
这个特定问题源于一个调试案例,该案例在循环内自动执行用户输入 - 并且由于 Chrome 在当前流程完成之前不会调用 $.ajax.always 回调,因此该流程不会标记为已完成。
示例代码:
procBox = []; // Global scope, stands for Process Box
function loadPolygons() {
procBox["loadPolygons"] = "running";
$.ajax({
// ajax things here
}).done(function() {
procBox["loadPolygons"] = "done";
}).fail(function() {
// failure stuff here
});
}
function dependentFunction() {
if procBox["loadPolygons"] === "done") {
// The meat of the function (dependentFunction things here)
} else {
// Backup case that allows the browser to retry the request
/* --
* If this fires, the server is still trying to process the
* ajax request. The user will be prompted to retry the request,
* and upon agreement, the function will be called again after
* 1 second passes.
*/
var msg = "Oops! It looks like we're still fetching your "
+ "polygons from the server. Press OK to retry.";
if (confirm(msg)) {
setTimeout(dependentFunction, 1000);
}
}
}
这种方法似乎在 Firefox 中效果很好 - alert()
会停止 JavaScript 执行,并为其提供发生 .done({})
回调的机会。但由于某种原因,while 循环永远不允许 .done({})
回调在 Chrome 中完成!
有谁知道比使用标志或 async: false
更好的方法吗?
我很感谢那里的任何答案和知识!
最佳答案
有很多方法可以做到: 正如已经建议的,你可以使用 由于您使用 jQuery,因此可以使用自定义事件 https://learn.jquery.com/events/introduction-to-custom-events/ :
$(document).on("myajax:done", function(){ dependentFunction();})
$.ajax({...}).done(function(){
$(document).trigger("myajax:done")
});
甚至全局ajax事件 https://api.jquery.com/category/ajax/global-ajax-event-handlers/
但要认真考虑为什么不做类似的事情
procBox = {onLoadPolygons:dependentFunction}; // Global scope
function loadPolygons() {
$.ajax({
// ajax things here
}).done(function() {
procBox["onLoadPolygons"]();
}).fail(function() {
// failure stuff here
});
}
function dependentFunction() {
alert("Please wait for the polygons to load");
dependentFunctionThings();
}
function dependentFunctionThings(){
// Do dependent function things...
}
更新: 如果你坚持你的结构,并且仍然想使用阻塞功能 使用setInterval执行检查
function dependentFunction() {
var h = setInterval(function() {
if (procBox["loadPolygons"] == "done") {
clearInterval(h);
// Do dependent function things...
}
}, 100);
}
或者将其包装成 Promise ( http://caniuse.com/#feat=promises )
function dependentFunction() {
(new Promise(function(resolve) {
var h = setInterval(function(){
if (procBox["loadPolygons"] == "done") {
clearInterval(h);resolve();
}
}, 100);
})).then(function(){
// Do dependent function things...
});
}
但我仍然相信你的结构有问题
关于javascript - 强制 Chrome 检查 $.ajax 调用是否已完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40577799/