强制Chrome检查$.Ajax调用结束

Force Chrome to check if a $.ajax call has finished?

本文关键字:调用 结束 Ajax Chrome 检查 强制      更新时间:2023-09-26

大家下午好-

是否有一种众所周知的方法来检查$.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/