Learn to Code via Tutorials on Repl.it!

← Back to all posts
Nodejs Typewrite effect
h
Coder100 (18118)

Typewriter effect

Here is something I hear a lot, nodejs is bad for terminal games! The thing is, it is. Imagine having to install an npm library just to get user input, and then have to learn how to make a typewriter effect! But it does teach you a lot -- in my opinion -- about asynchronous coding and being on top of everything.

First solution

In many programming languages, you would just loop through the text and write it out.
So that's what we try:

async function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }

async function typewriter(text, ms = 100) {
  for (const c of text) {
    process.stdout.write(c);
    await sleep(ms);
  }
}

(async() => {
  typewriter("hi there");
  console.log("done");
})();

Nothing printed! Why? Remember, as with all typewriter effects, we must flush the buffer, which we can't do, because it is nodejs, and flushing is a blocking operation, which is a big no-no.

Second Solution

Instead, we combat this cleverly with some recursion.

function typeWriter(text, speed = 100, done = () => {}) {
  process.stdout.write(text[0], () => {
    if (text.length > 1) setTimeout(() => typeWriter(text.slice(1)), speed);
    else done();
  });
}

typeWriter("hi there", () => console.log("done"));

How does this work? Well, the second function passed in is called when the terminal gets flushed. When we do that, we just do a setTimeout as our 'sleep' function, and then write the second character by slicing part of the text. It needs to stop somewhere, and it stops once the text is length > 1, because there is only one character left to print.

Asynchronous version

Of course, we must also add the usage of await :D

function typeWriter(text, speed = 100) {
  return new Promise((res) => {
    process.stdout.write(text[0], () => {
      if (text.length > 1) setTimeout(() => typeWriter(text.slice(1)), speed);
      else res();
    });
  });
}

(async() => {
  await typeWriter("hi there");
  console.log("done");
})();

Closing

Hope this made you hate js a bit more!

Comments
hotnewtop
CodeLongAndPros (1624)

If only I could downvote...
You brought the angst of teletype output and combined it with the pain of javascript programming.

codingjlu (215)

@CodeLongAndPros lololololol but you can't because he's CODER100 lol

CodeLongAndPros (1624)

@codingjlu "I'm delisting this, seeing as it's JavaScript and a typewriter effect, it can't stand"

DynamicSquid (4913)

@CodeLongAndPros Agreed, this is the ugliest thing I have ever seen. JS used to make effects for the console??