Рекурсивный метод с setTimeout - PullRequest
0 голосов
/ 26 июня 2018

Я пытаюсь создать объект js методом, который будет печатать букву за буквой с задержкой в ​​5 секунд между буквами.Но сейчас не работает.Он пишет это без задержки.Где моя ошибка?

class autoWrite{
    constructor(id,text){
        this.id = id;
        this.text = text;
    }
    startTyping(index=0){
        if(index==this.text.length){
            console.log("finish");
        }
        else{
            $("#"+this.id).append(this.text.charAt(index));
            setTimeout(this.startTyping(index+1),5000);
        }
    }
}
 a = new autoWrite("body-window","hello world");
 a.startTyping();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
 <div id="body-window">

</div>

Ответы [ 3 ]

0 голосов
/ 26 июня 2018

Сделайте это вместо:

 class autoWrite{
        constructor(id,text){
            this.id = id;
            this.text = text;
        }
        startTyping(index=0){
            if(index==this.text.length){
                console.log("finish");
            }
            else{
                $("#"+this.id).append(this.text.charAt(index));
                console.log(this.text.charAt(index))
                setTimeout(() => this.startTyping(index+1), 500);
            }
        }
    }
    
    
    a = new autoWrite("body-window","hello world");
    a.startTyping();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
 <div id="body-window">

</div>

В качестве альтернативы вы можете использовать setInterval() следующим образом (лучший подход):

 class autoWrite{
        constructor(id,text){
            this.id = id;
            this.text = text;
            this.index = 0;
        }
        startTyping(){
            if(this.index==this.text.length){
                console.log("finish");
                this.index += 1;
            } else {  $("#"+this.id).append(this.text.charAt(this.index));
                console.log(this.text.charAt(this.index));
                this.index += 1;
            }
        }
        start(){
           setInterval(() => {
             if(this.index <= this.text.length){
               this.startTyping();
             }
           }, 500);
          
        }
    }
    
    
    a = new autoWrite("body-window","hello world");
    a.start();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
 <div id="body-window">

</div>
0 голосов
/ 26 июня 2018

Как указано в документации setTimeout по MDN здесь , первый аргумент - это ссылка на функцию, которую необходимо выполнить после задержки.

Вы можете использовать следующий код.

class autoWrite{
    constructor(id,text){
        this.id = id;
        this.text = text;
    }
    startTyping(index=0){
        if(index==this.text.length){
            console.log("finish");
        }
        else{
            $("#"+this.id).append(this.text.charAt(index));
			let obj = this;
            setTimeout(function () {
				obj.startTyping(index+1);
            },5000);
        }
    }
}
 a = new autoWrite("body-window","hello world");
 a.startTyping();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
 <div id="body-window">

</div>
0 голосов
/ 26 июня 2018

С

setTimeout(this.startTyping(index+1),5000);

вы передаете результат startTyping как функцию, которая будет вызвана с setTimeout - undefined - он также вызывается немедленно без задержки.Попробуйте с:

var that = this;
setTimeout(function() {
  that.startTyping(index+1);
}, 5000);
...