Javascript 强制Chrome检查$.ajax调用是否已完成?

Javascript 强制Chrome检查$.ajax调用是否已完成?,javascript,jquery,ajax,google-chrome,Javascript,Jquery,Ajax,Google Chrome,大家下午好- 是否有一种众所周知的方法来检查$.ajax调用是否已完成 -比如说- 假设我使用$.ajax调用从.geojson文件异步加载大量传单多边形作为图层组。在正常情况下,这种情况几乎会立即发生,但用户这次选择加载一个大作业。用户假设多边形集已加载,并试图过早地对这组层执行某些操作-结果发现什么也没有发生-层组实际上还不存在于浏览器中 我的直觉是,我对web开发还不熟悉,需要设置某种全局标志,以便相关算法进行检查。我们将在加载层之前设置标志,然后在$.ajax调用的.done{}部分将其

大家下午好-

是否有一种众所周知的方法来检查$.ajax调用是否已完成

-比如说-

假设我使用$.ajax调用从.geojson文件异步加载大量传单多边形作为图层组。在正常情况下,这种情况几乎会立即发生,但用户这次选择加载一个大作业。用户假设多边形集已加载,并试图过早地对这组层执行某些操作-结果发现什么也没有发生-层组实际上还不存在于浏览器中

我的直觉是,我对web开发还不熟悉,需要设置某种全局标志,以便相关算法进行检查。我们将在加载层之前设置标志,然后在$.ajax调用的.done{}部分将其更改为其他值

-更新-

我重新编写了代码,允许用户选择是否重试请求,并强制浏览器在重试请求之前等待一段时间

然而,我也发现问题似乎出在Chrome上。Firefox似乎能够在完成$.ajax.always回调后立即处理$.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中似乎工作得很好-警报会停止JavaScript的执行,并给它一个发生.done{}回调的机会。但是由于某些原因,while循环从不允许.done{}回调在Chrome中完成

有人知道比使用标志或async:false更好的方法吗?
我很感激任何答案和知识

有很多方法可以做到: 如前所述,您可以使用 由于使用jQuery,因此可以使用自定义事件:

甚至是全局ajax事件

但是真正考虑为什么不做一些像

之类的事情。
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...
}
UPD: 如果你在你的结构上使用了ensist,并且仍然想使用阻塞函数 使用setInterval执行检查

function dependentFunction() {
    var h = setInterval(function() {
         if (procBox["loadPolygons"] == "done") { 
             clearInterval(h);
            // Do dependent function things...
        }
    }, 100);
}
或者把它包装成一个承诺

但是我仍然相信你的结构有问题,从文档中可以看出:

.ajaxComplete()
每当Ajax请求完成时,jQuery就会触发ajaxComplete事件。此时将执行使用.ajaxComplete方法注册的所有处理程序


不要无限期地阻止javascript。使用超时或间隔。阅读有关承诺的更多信息。你需要把你的头更多地缠绕在他们身上。也许你在寻找。永远。。。。这类似于try/catch的finnaly,但是对于jquery的done/fail,您可以看到这里的文档在发送之前向用户显示一些内容,或者在进行ajax时手动阻止UI的某些部分。看起来你一直都在关注这种情况,我想我在这里遗漏了一些东西——代码在firefox上运行良好,只是在Chrome上没有。在用户再次尝试编辑数据之前,我需要让javascript暂停片刻,以检查异步算法是否已完成。我不想在$.ajax完成后自动调用该函数-我只想检查当用户调用“dependentFunction”时,它是否仍在处理。@Dylan,我不知道dependentFunction在哪里以及如何调用,但如果它在Ff中工作,我很惊讶,只要运行Infinite循环,您的CPU就会受到冲击,您可以将您的检查总结为setTimeout=>{ifajaxEnd==1 doYourThings},100,但是您的while应该替换为if,在条件为true之后您会收到多少警报?警报会停止firefox中的javascript执行,并且回调仍会在幕后触发。10次中有9次,$.ajax在您单击警报上的[ok]之前完成,并且在第一次或第二次尝试时退出循环。然而,同样的方法在chrome中不起作用,这让我相信这种方法从根本上是错误的。我已经检查过将其包装在setTimeout函数中,这似乎可以从这里开始工作,但我还没有实现它。我已经用解决方案更新了答案,可以节省您的结构,但实际上,您已经做了一些准备,以及一些用户触发的操作,所以我只需要创建这两个事件,并在每个事件上检查是否发生了另一个事件,然后从其他语言启动依赖函数,我觉得我使用的结构一定有问题。我研究了您的一些建议,并添加了setTimeout函数以确保其正常工作。此外,我还发现chrome s
eems以不同于Firefox的方式处理$.ajax回调-这导致了在Firefox中工作出色,但在Chrome中陷入困境的问题。有趣的是-我想我正在关注。我是否可以创建某种类型的函数调用队列,在$.ajax完成后触发这些调用?现在,方法是尝试找到一种方法,当用户单击按钮时调用“dependentFunction”时,检查$.ajax函数是否仍在使用procBox[]标志进行处理。事实上,ajaxSuccess可能会更好,因为只有在使用HTTP 200响应完成ajax请求时才会调用它。ajaxComplete总是在ajax请求完成时执行。无论如何,只需将post ajax函数放在.ajaxComplete/.ajaxSuccessfunction中并使用它即可。Jquery文档和示例非常明确,我并不希望ajax请求一完成就发生什么,我只需要能够检查它是否已经完成。它在Firefox中完全可以正常工作!我更新了上面的主题,解释了在Chrome上运行这个程序的错误。也许我在承诺中遗漏了一些东西
function dependentFunction() {
   (new Promise(function(resolve) {
      var h = setInterval(function(){
         if (procBox["loadPolygons"] == "done") { 
             clearInterval(h);resolve(); 
         }

      }, 100);
   })).then(function(){
       // Do dependent function things...
   });
}
.ajaxComplete()