There can be times when you want an asynchronous function or event to wait and finish within a loop. But at the same time, you cannot break or stop the for loop from executing. Here in this example, I’ll be showing you a way to delay each iteration of a for loop using a simulated async function. I’ll create a custom sleep function, with the help of which, I’ll create a typing animation.
Here’s the code for the demo:
<template>
<div id="app">
<div
@click="playQuote()"
class="np-play-button"
:class="{
'np-play-button-black': isQuotePlaying,
'np-play-button-white': !isQuotePlaying,
}"
>
Play
</div>
<div>
<div class="np-quote-text">
<span>{{ quoteToDisplayString }}</span>
<span v-show="showBlinking">|</span>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Quote",
data() {
return {
quoteToDisplay: [],
quoteToDisplayString: "",
quoteString: `Die with memories, not dreams.`,
quotesList: [],
isQuotePlaying: false,
quoteTypingAnimationDelay: 100,
fontSize: 40,
showBlinking: false,
blinkingAnimationDelay: 300,
};
},
mounted() {
setInterval(() => {
this.showBlinking = !this.showBlinking;
}, this.blinkingAnimationDelay);
},
methods: {
sleep(milliseconds) {
return new Promise((resolve) => setTimeout(resolve, milliseconds));
},
async playQuote() {
if (this.isQuotePlaying) return;
this.quoteToDisplay = [];
this.quoteToDisplayString = "";
this.quotesList = this.quoteString.split("");
this.isQuotePlaying = true;
for (let i = 0; i < this.quotesList.length; i++) {
await this.sleep(this.quoteTypingAnimationDelay);
this.quoteToDisplay.push(this.quotesList[i]);
this.quoteToDisplayString = this.quoteToDisplay.join("");
if (i === this.quotesList.length - 1) this.isQuotePlaying = false;
}
},
},
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
background-color: rgb(24, 24, 24);
padding: 30px;
}
.np-play-button {
color: #fff;
padding-bottom: 30px;
cursor: pointer;
width: 200px;
height: 20px;
}
.np-play-button-white {
color: #fff;
}
.np-play-button-black {
color: rgb(24, 24, 24);
}
.np-quote-text {
font-size: 40px;
font-weight: bold;
line-height: 1.2;
color: #fff;
font-style: italic;
}
</style>
Code language: HTML, XML (xml)
In the example above, I’ve stored a quotation string in the quoteString local state. I’ve then converted it into an array of characters and stored in quotesList (line no 52). I’ve used quotesToDisplayString to show the appended strings, the new one replacing the old one with each iteration. The local state quotesToDisplayString will have the following values throughout the for loop: D, Di, Die, Die , Die w, Die wi, Die wit, Die with , Die with m, etc. When the loop is over, the full quote would be shown as: “Die with memories, not dreams.”
I’ve used a custom delay function called sleep on line 55. The method at line 44 has the body of the function. It returns a promise after waiting for the said delay time (in milliseconds).
Here’s a preview of the above code:
Demo links: