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

标签 javascript jquery ajax google-chrome

大家下午好 -

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

相关文章:

javascript - Bootstrap Tabs 不允许我更改 ID

jquery - Recaptcha Django cms - 验证码需要一分钟以上

javascript - 删除 Iframe 中的类

javascript - SweetAlert 的图像不出现

javascript - HTML5 退出视频全屏

javascript - 如何不在 ExtJS HTTPRequest 中传递 cookie

php - 从 javascript 中的 php 返回值获取值

javascript - 尝试使用双向数据绑定(bind)使用指令中的自定义代码更改 Material md-selected 选项卡

javascript - 难以捉摸的重新验证错误。复制代码总是失败

javascript - 在没有自动关闭标签的元素之前和之后插入内容