かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

JavaScript タイプライターみたいなエフェクト作ってみた。

単純に文字列を1文字づつ追加していくだけのものですが

See the Pen Text Typewriter with Javascript Promise by KIKIKI (@chaika-design) on CodePen.

※ 表示エフェクトはForkしたものですが、表示ロジックは丸っと作り直ました

PromiseはsetTimeoutを繰り返してもresolveを待つっぽい

エフェクトの終了を取りたかったのでとりあえずPromiseで実装してみたのですが、興味深いことに内部でsetTimeoutを繰り返していても最終的なresolveが実行されるのを待つようです。

実装していた部分

const typewriter = ($elm) => {    
  return new Promise((resolve, reject) => {
    const typeSpeed = 100;
    if($elm.length) {
      const text  = $elm.innerText;
      const chars = text.length;
      let index = 0;
      $elm.innerHTML = '';

      const write = () => {
        $elm.innerText += text[index];
        if(index < chars) {
          index += 1;
          setTimeout(() => write(), typeSpeed);
        } else {
          $elm.innerHTML = text;
          resolve('TYPEWRTER complete');
        }
      };
      write();
    } else {
      reject('TYPEWRTER no content');
    }
  });
};

文字列の長さ分setTimeoutを繰り返して最終的にresolveしています。呼び出し元はこのresolveを待ってthenが実行されました。
どうやらPromiseを返す関数は内部にresolverejectが有ることをチェックしてから実行されているっぽいですね。
関数内にresolverejectがあるけど、無限ループや動的な条件でresolveに辿り着けないような関数だとどうなるのでしょう…雰囲気的に待ち続けてしまいそうな気もしますが、タイムアウト的なところでundefinedresolveされるのでしょうか? (試す気がない


[参考]

Macのキーボードとほぼ同じなのでiPadで使うのにちょうどよい感じでした。