如何获得此代码以使序列明显?

时间:2014-08-20 22:23:27

标签: javascript

下面的代码允许我有一组数字,如#34; thearray = [2,8,9]"并循环遍历该数组,并且对于数组中的每个数字项,例如" 2,8,9",代码调用函数的次数等于数组中的当前数字项。因此,如果当前数字项为2,则函数将被调用两次。

在一组调用之后,有一个暂停,然后再次调用该函数的次数等于数组中的当前数字等。换句话说,当数组循环时,如果当前数字项为2,函数名为"函数"将被调用两次然后有一个暂停和功能"功能"然后再次被称为等于数组中下一个数字的次数。

就我而言,"功能"只需显示一个警告框消息两次,然后暂停,然后8次,然后暂停,然后9次,然后暂停等。当然,通过警报框消息,我按顺序获取消息,因为我必须选择确定在我看到下一条警报消息之前。问题是,我无法接听电话"功能"看起来是连续的,就像在"函数"中执行的代码一样。当其他代码(例如将带有数据的li项目附加到ul)在该函数内时,会显示一个警告框。

好像一次拨打2个电话,然后一次拨打8个电话,等等。即使情况可能并非如此,但它发生得如此之快,似乎就是这样。我想放慢速度。因此,如果代码在" thefunction"将信息附加到li元素的代码,而不仅仅是看到快速添加的信息,其中调用序列是不明显的,我希望有一个延迟,以便当附加li元素时,序列是更明显而不是快速,很难看到序列。

以下是代码:

function runArray(arr, fn) {
// initialize array index - can't use for loop here with async
var index = 0;

function next() {
   var cnt = +arr[index];
   for (var i = 0; i < cnt; i++) {
       fn(index, cnt);
   }
   // increment array index and see if there's more to do
   ++index;
   if (index < arr.length) {
       setTimeout(next, 400);
   }
}
// start the whole process if the array isn't empty
if (arr.length) {
   next();
}
 }

runArray(thearray, shakeit);

这是一个jsfiddle,演示了快速添加信息的日志。我想减慢它的速度,因此信息的添加速度足够慢,以显示有一个序列。

http://jsfiddle.net/jfriend00/Loycmb3b/

3 个答案:

答案 0 :(得分:1)

您想要做的事情是在for循环的执行之间插入延迟。引入JavaScript延迟的唯一理智方法是使用setTimeoutsetInterval,这就是您必须使用的内容。

接下来的想法是,因为每个循环迭代都要实现为对setTimeout和朋友的回调,所以在每个循环完成后移动到下一个数组元素的逻辑必然是其中的一部分 - - 在循环完成之前,您无法移动到下一个元素。

但移动到下一个元素的逻辑已经在next内,我们已经确定next应该设置回调。所以next将安排回调,回调也将安排next - 没有别的办法。

因此:

function runArray(arr, fn, delay) {
    var index = 0;
    var cnt = 0;
    var i = 0;

    // Called once for each array element    
    function next() {
        if (index >= arr.length) {
            return;
        }

        cnt = +arr[index];
        i = 0;
        loop();
    }

    // Represents a single iteration of what was previously a for loop
    // Will either schedule the next iteration or move to the next element
    function loop() {
        if (i < cnt) {
            fn(index, i++);
            setTimeout(loop, delay); // delay before next iteration
        }
        else {
            ++index;
            setTimeout(next, delay); // delay before moving to next element
        }
    }

    if (arr.length) {
        next();
    }
}

我在“循环迭代”和循环结束与下一个循环开始之间保持相同的delay,但这很容易改变。

<强> See it in action

答案 1 :(得分:1)

除非我误解了某些事情......

function runArray(arr, fn, delay, idx, cnt) {
    idx = idx || 0;
    cnt = cnt || 0;

    if(cnt >= arr[idx]) { 
        idx++; 
        cnt = 0; 
    }
    if(idx >= arr.length) 
        return;

    fn(idx, cnt);
    setTimeout(function() { runArray(arr, fn, delay, idx, cnt + 1) }, delay);
}

http://jsfiddle.net/Loycmb3b/8/

答案 2 :(得分:0)

我可能会或可能不会理解你想要做什么,但是这里有这段代码

runArray(theArray, theFunction, 400);

你正在执行theArray和theFunction在400毫秒后发生,1000秒是一秒,所以如果你想要它是一个更实质性的暂停,增加400,这里我把它增加到4000(4秒),暂停是更加值得注意的。

http://jsfiddle.net/Loycmb3b/7/