2017-02-20 111 views
0

循环在两个不同的阵列,两个for循环相互嵌套异步(如块和setTimeoutsourced from here),并试图用从W3Schools here(标签之一)进度条的例子。进度条使用嵌套for循环

的来源(稍微修改了 '完成' 回调)异步函数:

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

无论是asnychronous,这些是即使与正常for循环同样的问题:

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

  2. 有两个嵌套的for循环,所以不是跟踪(例如)ifor (var i=0...),它需要跟踪的第一循环*对于精度的第二循环的进展(如不出现停止 - 尤其是因为第二个循环可能会有比第一个更大的数组长度)。

例如:

异步使用上述链接例如:

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-loop歌剧灰。
  • 这些问题应该如何解决,最好不使用jQuery?

    +0

    但...你执行的代码盟友表演根本不是异步的。如果你想要一个进度条,你需要用'setTimeout()'或'setInterval()'而不是'for'来重写循环,就像你链接的代码一样。 – nnnnnn

    +0

    @nnnnnn请重新阅读第一段... – user1679669

    +1

    我在评论前阅读了两遍。你似乎在说“这是一些异步处理数组的代码,但我将忽略它,现在这里是一个简单的同步嵌套for循环,为什么不使用链接代码中的概念?关于进度条代码,你不需要一个单独的时间间隔,你可以从循环的相同函数中控制它。你想要一个进度条用于整体进度还是每个循环一个进度条? – nnnnnn

    回答

    1

    我认为这只是基本的增量。你可以使用这样的事情:

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


    随机执行时间的另一个例子(使用的承诺,做异步处理)

    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) { 
     
         \t //do something that require time 
     
         processing_something(resolve); 
     
         }).then(function(){ 
     
         \t progress(arr1.length * arr2.length); 
     
         }); 
     
        } 
     
    }
    <div id="progress"></div>

    +0

    这可能只是要走的路,谢谢!你知道如何限制'this.inc =(total!== 0?this.inc || 0:-1)+ 1;'根据总数来限制100%,而不是只输出总数? – user1679669

    +0

    我相信这会跑得太快,用户界面才能正确显示进度条...不知道这是否是您的需求。 – l3utterfly

    +0

    @ l3utterfly我认为他可以把这个进度作为一个回调在他的函数内循环 – Fal