具有嵌套For循环的进度条

时间:2017-02-20 02:20:53

标签: javascript loops for-loop asynchronous progress-bar

循环遍历两个不同的数组,两个for循环以异步方式彼此嵌套(如chunks和setTimeout sourced from here),并尝试使用W3Schools here中的进度条示例(标签一)。

sourced(稍微修改为'done'回调)异步函数:

function loopAsync(array, fn, done, chunk, context) {
    context = context || window;
    chunk = chunk || 10;
    var index = 0;

    function doChunk() {
        var cnt = chunk;
        while (cnt-- && index < array.length) {
            // callback called with args (value, index, array)
            fn.call(context, array[index], index, array);
            ++index;
            //console.log("index is " + index);
            progressBar(index);
        }
        if (index < array.length) {
            // set Timeout for async iteration
            setTimeout(doChunk, 1);
        } else {
            done && done();
        }
    }
    doChunk();
}

即使是非同步的,即使使用正常的for循环,这些也是同样的问题:

  1. W3School示例使用setInterval,这是不准确的,因为for循环可能已经在setInterval之前完成处理。

  2. 有两个嵌套的for循环,因此它不需要跟踪i中(例如)for (var i=0...)的进度,而是需要跟踪第一个循环*第二个循环以获得准确性(至于没有出现停止 - 特别是因为第二个循环的阵列长度可能比第一个循环长。)

  3. 例如:

    异步使用上面的链接示例:

    loopAsync(arr1, function (item1) {
        loopAsync(arr2, function (item2) {
            //Comparing or processing item1 with item2
        });
    }, doNext);
    

    或者,没有异步循环基本相同:

    for (var item1 = 0; item1 < arr1.length; ++item1) {
        for (var item2 = 0; item2 < arr2.length; ++item2) {
            //Doing things... need to track progress of both?
        }
    }
    
    1. 需要是通用的,能够在任何嵌套(或非嵌套)for循环操作中使用。
    2. 如何解决这些问题,最好不要使用jquery?

1 个答案:

答案 0 :(得分:1)

我认为这只需要基本的增量。你可以使用这样的东西:

&#13;
&#13;
qgis
&#13;
&#13;
&#13;

具有随机执行时间的另一个示例(使用承诺执行异步处理)

&#13;
&#13;
function progress(total) {
  this.inc = (total !== 0? this.inc || 0: -1) + 1;
  var percentage = Math.floor(this.inc / total * 100);
  document.write('Processing ' + this.inc + '/' + total + ' ' + percentage + '%<br/>');
}

var arr1 = [1,2,3,4,5];
var arr2 = [1,2,3,4,5,6,7,8,9];

for (var item1 = 0; item1 < arr1.length; ++item1) {
  for (var item2 = 0; item2 < arr2.length; ++item2) {
      progress(arr1.length * arr2.length);
  }
}

// reseting counter
progress(0);

// count another progress
var arr3 = [1,2,3];

for (var item1 = 0; item1 < arr1.length; ++item1) {
  for (var item2 = 0; item2 < arr2.length; ++item2) {
    for (var item3 = 0; item3 < arr3.length; ++item3) {
        progress(arr1.length * arr2.length * arr3.length);
    }
  }
}
&#13;
function progress(total) {
  this.inc = (total !== 0? this.inc || 0: -1) + 1;
  document.getElementById('progress').innerHTML = 'Processing ' + Math.floor(this.inc / total * 100) + '%';
}

function processing_something(callback) {
  setTimeout(function(){
    callback();
    //execution between 1 to 10 secs
  }, Math.floor(Math.random() * 10) * 1000);
}

var arr1 = [1,2,3,4,5];
var arr2 = [1,2,3,4,5,6,7,8,9];

for (var item1 = 0; item1 < arr1.length; ++item1) {
  for (var item2 = 0; item2 < arr2.length; ++item2) {
      new Promise(function(resolve) {
      	//do something that require time
        processing_something(resolve);
      }).then(function(){
      	 progress(arr1.length * arr2.length);
      });
  }
}
&#13;
&#13;
&#13;