javascript - 带有嵌套 For 循环的进度条

标签 javascript loops for-loop asynchronous progress-bar

循环两个不同的数组,两个 for 循环都异步嵌套(作为 block 和 setTimeout sourced from here ),并尝试使用 W3Schools here 中的进度条示例(标签之一)。

源异步函数(针对“完成”回调稍作修改):

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 循环,因此不要在 for (var i=0...) 中跟踪(例如)i 的进度>,它需要跟踪第一个循环 * 第二个循环以确保准确性(以免显得停止 - 特别是因为第二个循环可能具有比第一个循环更大的数组长度)。

例如:

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

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?
    }
}
  • 需要是通用的,能够在任何嵌套(或非嵌套)for 循环操作中使用。
  • 应该如何解决这些问题,最好不用jquery?

    最佳答案

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

    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);
        }
      }
    }

    <小时/>

    另一个具有随机执行时间的示例(使用 Promise 执行异步过程)

    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);
          });
      }
    }
    <div id="progress"></div>

    关于javascript - 带有嵌套 For 循环的进度条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42335488/

    相关文章:

    javascript - 如果没有 `<slot/>` 而是影子根,子节点会发生什么

    Ruby 嵌套 while 循环提前停止

    php - PHP的 Assets 错误回显其他

    java - 如何使用 for 循环更改数组中的值

    javascript - 为 for 循环添加时间延迟

    python - 你能 "restart"Python 循环的当前迭代吗?

    Javascript - 定义图像树的有效方法

    javascript - Backbone.js View 中的 this.el 究竟是什么?

    php - HTML onclick 不触发函数

    php - 如何读取 PHP foreach 循环中的数组?