【问题标题】:Javascript - Loop keeps running after page refreshJavascript - 页面刷新后循环继续运行
【发布时间】:2014-05-12 21:06:27
【问题描述】:

今天发生了我见过的最奇怪的事情之一。 我在页面中有一个循环,它为循环的每个元素执行同步 ajax 请求。由于花费的时间太长,我决定通过刷新页面来停止循环。

当页面加载时,我无法单击页面的任何元素,所以我检查了 Firebug 控制台,我看到前一个循环的 ajax 调用仍在完成(循环设置为在我单击后开始链接,因此它无法在页面加载后立即启动)。 要停止循环,我必须关闭当前标签并在新标签中打开我的页面。

值得一提的是,我在该页面上有一个数据表,并且我启用了保存表状态的选项,这可能会干扰我的代码(循环本身不是数据表初始化的一部分,尽管它使用数据表)。

我还注意到循环中的某些事情没有完成。它应该不时更改数据表的页面,并且应该在javascript控制台中编写,刷新页面后这两件事都没有发生,ajax调用仍在进行。

这是包含循环的代码:

//This variable will contain a reference to the datatable
var oTable;
var isWorking=false;
//Change the datatables page
function changeTablePage(oTable, page, clear){
    if(clear){
        oTable.fnClearTable();
        oTable.fnDraw();
    }
    oTable.fnPageChange(page);
}

//This part is inside a document.ready block
    $(document).on("click", ".validation-all-click", function(event){
        if(!isWorking){
            isWorking=true;
            //saves the current page, will be needed for later
            var page=oTable.fnPagingInfo().iPage;
            var numberPage=0;
            var done=false;
            while(!done){
                console.log("page: "+numberPage);
                changeTablePage(oTable, numberPage, false);
                var nNodes = oTable.fnGetNodes();
                var len=nNodes.length;
                $('.validation-click', nNodes).each(function( index, value ){
                    //id of the element to be validated
                    var id=$(value).data("rowid");
                    //Calls the validation url
                    $.ajax({
                        url: "/validate?id="+id,
                        async: false
                    });
                });
                //if the datatables page has 0 items, then it's done
                if(len==0){
                    done=true;
                }
                numberPage++;
            }
            //goes back to the original page
            changeTablePage(oTable, page, true);
            isWorking=false;
        }

});

我不希望这种行为发生,但我不知道为什么会发生以及如何防止它发生

【问题讨论】:

  • 这不太可能是您看到所见的原因。如果您在哪里提供简化的案例,有人可能会提供帮助。
  • 我已经发布了包含循环的代码
  • 表面上看起来是正确的。一个 firbug 错误将在我的嫌疑人名单上。甚至可能是一个 Firefox 错误。不过,你的方法是错误的。请求应该是异步的。我只使用async: false 进行原型设计。
  • 这个循环可能会在 100k 或更多的数据集上调用,除非有办法将 ajax 调用排队而不是一次全部执行(我承认我从未寻找过),如果我不这样做t 使用 async: false 浏览器(甚至服务器)可能会冻结或崩溃。但我担心排队 ajax 调用会遇到与我现在遇到的问题相同的问题
  • 我可能会补充一点,这是 Firefox 上的行为(准确地说是 Pale Moon),我刚刚在 Chrome 上尝试了该页面:在这种情况下,如果我单击刷新脚本继续运行,但页面如果我单击刷新按钮,则根本不会刷新。

标签: javascript ajax datatables refresh


【解决方案1】:

我已经通过添加一个变量来解决,该变量将在我退出页面时停止循环:

var stopLoop=false
$( window ).unload(function() {
    stopLoop=true;
});

两个循环现在将在执行循环内的代码之前检查此变量是否为假。 这适用于 Firefox,但不适用于 Chrome。

-- 编辑--

最后我通过编辑代码以使 ajax 调用异步并使用回调函数继续循环来解决,尽管这不是一个简单的任务(几天后我找到了一个新的解决方案,让我当我发现如何恢复数据表用于检索数据的参数时,只需一次调用即可完成我需要的所有操作,但这与原始问题无关)。因此,供将来参考:在使用 ajax 同步调用进行循环时,请期待这种“奇怪”的行为

【讨论】:

    【解决方案2】:

    感谢您分享您的故事。我在帖子中没有看到任何具体问题,所以我只会评论我的感受。

    据我了解,浏览器不需要在 JavaScript 运行时重绘 UI。由于在同步 ajax 请求上存在脚本阻塞,因此在循环结束之前您可能看不到表的更改。

    此外,浏览器也可能不需要在其脚本运行时销毁页面。这可以解释为什么您在刷新页面后在 Firebug 中看到了请求——可能页面的先前副本仍然在隐藏状态下运行。

    编辑:valepu 在下面的评论中报告,该表在脚本运行时确实发生了变化。没关系。浏览器可能会确定它可以在 ajax 调用期间重绘 UI(这不会影响 JavaScript 环境)。 valepu 还澄清了刷新页面后视觉更新停止,尽管请求继续发出。这也与浏览器刚刚隐藏上一个页面(直到它完成)并在刷新时加载了该页面的新副本的想法一致。

    至于如何防止它:最可靠的方法是使用异步请求,或者在请求之间屈服。对不起,伙计们。

    【讨论】:

    • “问题”是我不希望这种行为发生,但我不知道它为什么会发生以及如何防止它。当我单击启动循环的按钮后脚本运行时,我看到表发生变化(和 console.log 消息),刷新页面后,我仍然看到 ajax 调用(对数据表页面的调用和循环中的调用),但我没有看到控制台消息或正在更新的表。
    猜你喜欢
    • 2014-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-26
    • 1970-01-01
    • 2019-02-26
    • 1970-01-01
    • 2017-06-13
    相关资源
    最近更新 更多