setTimeout Does not Wait The Time

Asked

Viewed 463 times

1

I Have This Code:

<html>
    <form method="POST">
        <textarea name="txt" value="" rows="5" cols="100"></textarea>
        <br></br>
        <input type="button" name="" value="Message" onClick="btfunc()" style="width:100; height:100" wrap="soft">
    </form>
    <script charset="utf-8">
        var strs = ["C++", "Python"];
        var i = 0;
        var strpos = 0;

        function btfunc()
        {
            while (i < strs[strpos].length)
            {

                if (strpos > strs.length - 1)
                {
                    break;
                }
                else
                {
                    if (i == strs[strpos].length - 1)
                    {
                        document.forms[0].elements[0].value += strs[strpos].charAt(i);
                        i = -1;
                        strpos++;
                        document.forms[0].elements[0].value += "\n";
                        i++;
                        setTimeout(btfunc, 2000);
                    }
                    else
                    {
                        document.forms[0].elements[0].value += strs[strpos].charAt(i);
                        i++;
                        setTimeout(btfunc, 100);
                    }
                }

            }

        }
    </script>

</html>

When I Click the Button It Inserts All Text Without Pausing In SetTimeouts, Pq It Happens ?

  • This code is a bit confusing. Can you explain what you want to do? (apart from the problem with timeouts...)

  • He’ll write down whatever’s on array and from one element to the other he jumps a line in the textarea, only with an effect of (Typing) example:C (0.1Sec After) + (0.1Sec After) + Got it ?

  • After finishing an element it skips a wait line two seconds and starts writing the other element of array, the code works the way I want the problem is that it does not pause.

1 answer

3


Your main problem is calling setTimeout(func, 100). That is, the cycle while runs and creates a "wait list" with these setTimeout. Once the code finishes execution even before the first setTimeout be run in practice all setTimeout point to the same moment and are written at the same time. The solution is to delay execution by creating increasing values for each setTimeout.

Trying to mix your idea with my logic I suggest this:

var strs = ["C++", "Python"];
var i = 0;

function maquinaEscrever(str) {
    var campo = document.forms[0].elements[0];
    var pedacos = str.split('');

    pedacos.forEach(function (letra, index) {
        setTimeout(function () {
            campo.value += letra;
            if (index + 1 == pedacos.length){
                setTimeout(btfunc, 2000);
                campo.value += '\n';
                i++;
            }
        }, index * 100);
    });
}

function btfunc() {
    if (strs[i]) maquinaEscrever(strs[i]);
    else i = 0;
}
<form method="POST">
    <textarea name="txt" value="" rows="5" cols="100"></textarea>
    <br></br>
    <input type="button" name="" value="Message" onClick="btfunc()" style="width:100; height:100" wrap="soft" />
</form>

So divide the code into parts. I created a callback which is what calls the function btfunc once again the first string have been written.

I created a "typewriter" that in the background part a stirng in letters and writes a seperadas by 100 milliseconds. I used the index/position of the letter in the string to make this milliseconds difference seen this forEach run right away.

I don’t understand why you use a textarea, I could use a div, but I didn’t touch that part because the problem wasn’t there.

  • I’m analyzing your code here, but you know why setTimeout wasn’t working ?

  • @axell13 yes, because all were run at the same time. The 100ms that you’re putting on will all be run at the same time because the loop doesn’t stop to wait for the setTimeout. That’s why I used i * 100. Which in practice is 100, 200, 300, etc..

  • @axell13 I have to go, I had an answer about that problem somewhere here in Sopt (well explained). If you do not understand yet the problem I will put here tomorrow. I hope to have helped.

  • It helped me yes, thank you, the important thing here was that setTimeout inside the loop not right.

  • The part that would like to intend right is to multiply the index by 100, what has in the setTimeout that has to do this ? By the way when I try to put @Sergio at the beginning of the comment it does not come out.

  • 1

    @axell13 All the "footsteps" of your while occur very close to each other. As Sergio said, timeouts all expire together. Multiplying the index by 100 is a way to "ward off" the timers from each other.

  • @bfavaretto I understand but everything should happen normally, for me this seems more like a bug of the language than lack of knowledge of the programmer. In other languages for example it has no problem to put a Sleep inside a loop.

  • @axell13 setTimeout It works different than a Slleep, his callback is asynchronous. Take a look here: http://answall.com/questions/16950/como-programa%C3%A7%C3%A3o-ass%C3%Adncrona-funciona-em-javascript/16960#16960

  • Yeah, I knew it was different, I just think it’s dirty not to be able to stop the execution anyway, but thanks.

  • 1

    @axell13 stopping Javascript execution is considered a programming error, even if it is practical. Sometimes I feel like making an ajax syncrono request but the reasons for not doing it are bigger. You can do for example with setInterval create a loop but in this case I think it would be better as I suggested.

  • @Sergio Yes, Just a Question I Don’t Know If You Can Answer, When You Put split('') OK Normal But When You Put split("") He Converts This Constant To '' ?

  • @axell13 what do you mean by "He Converts This Constant"? what constant? using double or single quotes is the same if you have nothing inside the quotation marks.

  • @Sergio Forgets This Part, Just To Know Even When I Put "" He wastes time turning this into '' ? Or whatever will have the same performance ? Even if it changes very little and is imperceptible it wastes time transforming ?

  • @axell13 there is no difference between single and double quotes. It is usually used ' in Javascript because in HTML it is used " as a rule, in this way they shock less.

  • @Sergio Is Because For Example In Python If You Put "Hello" On The Console It Will Return 'Hello' Was That My Question.

  • @Sergio That’s why I thought he had to transform

  • @axell13, I spoke in Javascript. In other languages it is/may be different. Take a look here for example: http://answall.com/questions/4652/diff%C3%A7a-between-single-double-quote-in-php

  • @Sergio Link Interesting, Now I know when it is best to use each one, thank you.

Show 13 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.