大家下午好-
是否有一种众所周知的方法来检查$.ajax
呼叫是否已经完成?
—FOR INSTANCE—
假设我使用$.ajax
调用从.geojson文件加载大量传单多边形(异步作为图层组)。在正常情况下,这几乎会立即发生——但是用户这次选择加载一个大型作业。用户假设多边形集已经加载,并试图过早地对这组图层做一些事情-只是发现什么都没有发生(该图层组实际上还不存在于浏览器中)。
我的直觉(我是新的web开发)是有某种全局标志,设置依赖算法来检查。我们将在加载层之前设置标志,然后将其更改为$.ajax
调用的.done({})
部分中的其他值。
——UPDATE——
我重新编写了代码,允许用户选择他们是否希望重试请求,并且还强制浏览器在重试请求之前等待一段时间。
然而,我也发现这个问题似乎是与Chrome。Firefox似乎能够处理$.ajax。总是在它完成后立即回调(换句话说,就是$.ajax. js。Always callback会中断javascript的正常流程)。
Chrome似乎阻止了$.ajax。
总是回调,只让它执行后,所有其他javascript已经完成运行(没有中断)。这个特殊的问题源于一个调试案例,在一个循环中自动用户输入-因为Chrome不调用$.ajax。总是回调,直到当前进程完成,进程不被标记为完成。
示例代码:
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...
});
}
但我仍然认为你的结构有问题
From the docs:
.ajaxComplete()
当Ajax请求完成时,jQuery触发ajaxComplete事件。所有在. ajaxcomplete()方法中注册的处理程序都将在此时执行。
http://api.jquery.com/ajaxcomplete/