我有一个数据集,在该数据集上迭代并在每个元素上运行相当繁重的操作。为了防止浏览器冻结,我将超时设置为0ms。虽然浏览器不会冻结,但是根据用户的输入,计算可能需要花费好几秒钟的时间。这是代码:

function calculation(){
    $.each(data,function(key,value){
        setTimeout(function(){
            doTheHeavyLifting(value);
        },0);
    });
}


现在的问题是,如果用户要求使用新值再次运行计算,我想停止先前的计算。

我尝试在函数外部定义continueCalculating布尔值,并在调用false之前在runCalculation()中将其设置为calculation(),然后在calculation()内部将其重置为true。这是修改后的代码:

var continueCalculating=false;

function runCalculator(){
    continueCalculating=false;
    calculation();
}

function calculation(){
    continueCalculating=true;
    $.each(data,function(key,value){
        setTimeout(function(){
            if(continueCalculating){
                doTheHeavyLifting(value);
            }else{
                console.log("Abort the mission!");
                return false;
            }
        },0);
    });
}


好吧,这并不能解决问题,回想起来,这还是一个很愚蠢的主意。因此,接下来我也尝试清除所有超时。这是修改后的代码:

var continueCalculating=false;
var operationQueue=[];

function runCalculator(){
    continueCalculating=false;
    $.each(operationQueue, function(k,v){
        clearTimeout(v);
    });
    calculation();
}

function calculation(){
    continueCalculating=true;
    $.each(data,function(key,value){
        operationQueue.push(setTimeout(function(){
            if(continueCalculating){
                doTheHeavyLifting(value);
            }else{
                console.log("Abort the mission!");
                return false;
            }
        },0));
    });
}


好吧,那也没有产生任何结果。

我知道$.eachfor慢,但是要迭代的项目大约只有几十个,因此这里肯定不是瓶颈。我不是在寻找优化此代码的方法,我只需要停止正在进行的计算即可。这可能吗?

最佳答案

您应该异步迭代:



var data = [0,1,2,3,4,5,6,7,8,9,"end"];
function doTheHeavyLifting(value) {
  console.log(value);
}
function calculation(data) {
  var key = 0, timer;
  (function loop() {
    if(key < data.length) {
      doTheHeavyLifting(data[key]);
      key++;
      timer = setTimeout(loop, 1e3);
    }
  })();
  return {stop: function() { clearTimeout(timer) } };
}
var calc = calculation(data);
document.querySelector('#stop').onclick = calc.stop;

<button id="stop">Stop</button>

09-06 15:14