如何在数组javascript中使用split()和setTimeout()

时间:2021-11-22 21:44:47

It may be a little confusing :S

这可能有点令人困惑:S

If anyone can help me to split an array of strings into letters. And than to tape it with time-outs. Like in DOS.

如果有人可以帮我把字符串数组分成字母。而不是用超时带来它。就像在DOS中一样。

I can do this with single strings, but i can't do it in arrays.

我可以使用单个字符串执行此操作,但我无法在数组中执行此操作。

Here is my code:

这是我的代码:

var text = new Array();
text[0] = "welcome ".split('');
text[1] = "how are u?".split('');
var delay = 20;
for (var j = 0; j < text.length; j++) {

    var txt = text[j];
    for (u = 0; u < txt.length; u++) {
        setTimeout(function () {
            $('div#console_div').append('<br />' + txt.shift());
        }, delay * j + 100);
    }
}

2 个解决方案

#1


3  

This is how I would do it. Instead of a for loop, use a recursive function which calls itself with different arguments depending on where it is on the string(s):

我就是这样做的。而不是for循环,使用递归函数,该函数使用不同的参数调用自身,具体取决于它在字符串上的位置:

var text = new Array();
text[0] = "welcome ".split('');
text[1] = "how are you?".split('');
var delay = 400;

function addOneChar(i, j) {
    $('#console_div').append('<br>' + text[i][j]);
    if (j+1<text[i].length) {  // next character in the current string
        setTimeout(function() { addOneChar(i, j+1); }, delay);
    } else if (i+1<text.length) {   // start the next string in the text[] array
        setTimeout(function() { addOneChar(i+1, 0); }, delay);
    } // else quit
}

setTimeout(function() { addOneChar(0,0); });

http://jsfiddle.net/mblase75/tkEDN/

We could simplify this further by combining text[] into a single string and using .charAt() to extract characters:

我们可以通过将text []组合成一个字符串并使用.charAt()来提取字符来进一步简化:

var text = new Array();
text[0] = "welcome ";
text[1] = "how are you?";
var delay = 400;
var textstr = text.join('');

function addOneChar(i) {
    $('#console_div').append('<br>' + textstr.charAt(i));
    if (i+1<textstr.length) {
        setTimeout(function() { addOneChar(i+1); }, delay);
    } // else quit
}

setTimeout(function() { addOneChar(0); });

http://jsfiddle.net/mblase75/MYtjy/

#2


3  

You have the typical "closure in a loop" problem. Have a look at JavaScript closure inside loops – simple practical example. At the moment the timeout callbacks are executed, txt refers to text[1]. All the timeouts are still executed though, so you are calling txt.shift() more often than there are elements in the array.

你有典型的“循环闭合”问题。看看循环中的JavaScript闭包 - 简单实用的例子。在执行超时回调时,txt引用文本[1]。所有超时仍然执行,因此您比数组中的元素更频繁地调用txt.shift()。

Another problem is that any delay up to 100ms is hardly noticeable by any human being, so you don't see any increment. Even worse, for the first phrase, all timeouts are executed at the same time (nearly), since j is 0 and delay * j + 100 will result in 100.

另一个问题是任何人都难以察觉任何延迟达100毫秒的延迟,所以你看不到任何增量。更糟糕的是,对于第一个短语,所有超时都在同一时间(几乎)执行,因为j为0而延迟* j + 100将导致100。


You are better off processing each letter one by one instead of creating all the timeouts at once (note that Blazemonger's solution is the same, but easier to understand since it is cleaner).

你最好逐个处理每个字母而不是一次创建所有超时(注意Blazemonger的解决方案是相同的,但更容易理解,因为它更干净)。

var text = [...];

function printLetter(phrase_index, letter_index) {
    var word = text[phrase_index];
    if (word) {
        if (letter_index === word.length) {
            printLetter(phrase_index + 1, 0);
        }
        else {
            var letter = word[letter_index];
            if (letter) {
                $('div#console_div').append('<br />' + letter);
                setTimeout(function() {
                    printLetter(phrase_index, letter_index + 1);
                }, 200);
            }
        }
    }
}

printLetter(0, 0);

DEMO

#1


3  

This is how I would do it. Instead of a for loop, use a recursive function which calls itself with different arguments depending on where it is on the string(s):

我就是这样做的。而不是for循环,使用递归函数,该函数使用不同的参数调用自身,具体取决于它在字符串上的位置:

var text = new Array();
text[0] = "welcome ".split('');
text[1] = "how are you?".split('');
var delay = 400;

function addOneChar(i, j) {
    $('#console_div').append('<br>' + text[i][j]);
    if (j+1<text[i].length) {  // next character in the current string
        setTimeout(function() { addOneChar(i, j+1); }, delay);
    } else if (i+1<text.length) {   // start the next string in the text[] array
        setTimeout(function() { addOneChar(i+1, 0); }, delay);
    } // else quit
}

setTimeout(function() { addOneChar(0,0); });

http://jsfiddle.net/mblase75/tkEDN/

We could simplify this further by combining text[] into a single string and using .charAt() to extract characters:

我们可以通过将text []组合成一个字符串并使用.charAt()来提取字符来进一步简化:

var text = new Array();
text[0] = "welcome ";
text[1] = "how are you?";
var delay = 400;
var textstr = text.join('');

function addOneChar(i) {
    $('#console_div').append('<br>' + textstr.charAt(i));
    if (i+1<textstr.length) {
        setTimeout(function() { addOneChar(i+1); }, delay);
    } // else quit
}

setTimeout(function() { addOneChar(0); });

http://jsfiddle.net/mblase75/MYtjy/

#2


3  

You have the typical "closure in a loop" problem. Have a look at JavaScript closure inside loops – simple practical example. At the moment the timeout callbacks are executed, txt refers to text[1]. All the timeouts are still executed though, so you are calling txt.shift() more often than there are elements in the array.

你有典型的“循环闭合”问题。看看循环中的JavaScript闭包 - 简单实用的例子。在执行超时回调时,txt引用文本[1]。所有超时仍然执行,因此您比数组中的元素更频繁地调用txt.shift()。

Another problem is that any delay up to 100ms is hardly noticeable by any human being, so you don't see any increment. Even worse, for the first phrase, all timeouts are executed at the same time (nearly), since j is 0 and delay * j + 100 will result in 100.

另一个问题是任何人都难以察觉任何延迟达100毫秒的延迟,所以你看不到任何增量。更糟糕的是,对于第一个短语,所有超时都在同一时间(几乎)执行,因为j为0而延迟* j + 100将导致100。


You are better off processing each letter one by one instead of creating all the timeouts at once (note that Blazemonger's solution is the same, but easier to understand since it is cleaner).

你最好逐个处理每个字母而不是一次创建所有超时(注意Blazemonger的解决方案是相同的,但更容易理解,因为它更干净)。

var text = [...];

function printLetter(phrase_index, letter_index) {
    var word = text[phrase_index];
    if (word) {
        if (letter_index === word.length) {
            printLetter(phrase_index + 1, 0);
        }
        else {
            var letter = word[letter_index];
            if (letter) {
                $('div#console_div').append('<br />' + letter);
                setTimeout(function() {
                    printLetter(phrase_index, letter_index + 1);
                }, 200);
            }
        }
    }
}

printLetter(0, 0);

DEMO