【问题标题】:Exiting a for loop with button in Javascript在Javascript中使用按钮退出for循环
【发布时间】:2015-07-13 17:49:06
【问题描述】:

嘿,当用户按下停止按钮退出循环时,我一直很难让我的代码识别。我知道这是一个线程问题,但我一直在尝试使用 setTimeout/setInterval 解决这个问题。

在我的代码中,我有一个带有onclick="stop()" 的按钮,其功能为stop(){cancel = true;}。在我的代码中,我有一个 .each 循环,它遍历某些行一定次数(取决于选中的复选框的数量)。每次迭代都会调用Row(this);,除了一些检查和getter 之外,它还包含一个for 循环,用于迭代当前行的总长度。就像这样:

for (i = 0; i < row.length; i++) {      
    ajaxCallForRowSingle(row[i]);

    if (stop == true) {
        return false; }
}  

我已经尝试过setTimeout(ajaxCallForRowSingle(row[i]),0);,但我得到“找不到语法错误标签”,我认为这是来自 ajax 调用。有解决办法吗?我的按钮按下总是排队并在循环后执行。

【问题讨论】:

    标签: javascript jquery jquery-ui for-loop


    【解决方案1】:

    好的,这就是你需要做的......

    不要使用“for”循环,而是创建一个函数并使用“setTimeout”或“setInterval”递归调用它

    var iRowsToProcess = row.length;
    var iRowIndex = 0;
    var processRows = function(){
        if (!stop){
            ajaxCallForRowSingle(row[iRowIndex]);
            iRowIndex++;
            if (iRowIndex < iRowsToProcess){
                setTimeout(processRows, 1);
            };
        };
    };
    
    setTimeout(processRows, 1);
    

    此代码将递归调用“processRows”,直到处理完所有行,或者直到“stop”为 false。美妙之处在于,每个“setTimeout”调用都是异步处理的,这意味着它允许其他 JS 代码在再次调用之前更新。它释放所有 JS 代码同步等待的一个线程。

    【讨论】:

    • 非常感谢!看起来它正在工作。奇怪的是,我在第一次迭代时打开了一个对话框(来自 JQuery ui)。该框在 for 循环中打开良好,但在更改为递归解决方案时根本不打开。这可能是由于匿名函数的原因吗?
    • 你指的是哪个盒子?你能发布与“盒子”打开相关的 HTML 和任何其他 JS 代码吗?
    • 好的,我为对话框添加了实现的基本思想
    • 那么,这条线是什么... 'if($('#current')==0){' 试图完成?
    • 据我所知,除非您试图确定 'if' 语句,否则可以删除 'if($('#current')==0){'。这很可能是您的问题的根源。
    【解决方案2】:

    我认为您正在寻找一个调用自身而不是 for 循环的递归函数。另外,要中断 for 循环,我会使用“break”而不是尝试返回 false。

    设置一个递归函数以继续调用自身,直到您找到所需的 row.length。

    【讨论】:

    • 我害怕那个。我只使用return false,因为它打破了 .each 循环
    • 返回 false 或 true(或返回任何内容)将跳出 .each 循环,因为 .each 实际上正在运行一个函数,并且返回函数外部的值。常规的 for 循环只是一段反复运行且没有返回值的代码。
    • 那么使用返回选项不是比跳出循环然后返回更快吗?抱歉,我忘了补充一点,当按下停止按钮时,我想退出两个循环,但只是跳出 for 循环是我最大的问题(因为不会设置停止)
    【解决方案3】:

    如果您想使用 setTimeout 或 setInterval,则必须将 ajaxCall 包装在另一个函数中,例如,

    setInterval(function () {
        ajaxCallForRowSingle(row[i]);
    }, 0);
    

    您可以通过将其ID存储为变量来清除间隔,然后调用clearInterval,例如,

    var i = 0;
    var id = setInterval(function () {
        ajaxCallForRowSingle(row[i]);
        i++;
        if (i >= row.length) { clearInterval(id); }
    }, 0);
    
    var stop = function () {
        clearInterval(id);
    }
    

    【讨论】:

    • 我确实尝试过,但我的代码无限期地运行。间隔一直在继续。是否有什么我错过了阻止它不断运行?
    猜你喜欢
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 2012-05-15
    • 2022-01-18
    相关资源
    最近更新 更多