JavaScript
2022.12.08
JavaScriptでsleep機能を実装!awaitやpromiseを使う方法
2023.11.15

今回は、JavaScriptでsleep機能を実装する方法について解説していきます。


本記事では、


「一般的なsleep機能とは?」

「JavaScriptでsleep機能を実装するには?」

「JavaScriptでsleep機能を実装するのに、おすすめのやり方は?」


といった内容を、初級者エンジニア向けに詳しく解説していきます。



1.     sleep機能とは?

sleepは、プログラムの実行を一時停止する機能です。

主にループ処理やスレッド処理において、メイン処理を一時停止することで、CPUの負荷を抑えるために使われます。

メイン処理の負荷が下がるタイミングでsleep処理から復帰することで、CPU負荷に余裕をもって処理が再開できます。



2.JavaScriptにはsleepメソッドがない


実はJavaScriptには、他の言語にあるようなsleepメソッドというものはありません。

別のメソッドを利用してsleep機能を代替する必要があります。


本記事で紹介するコーディング方法は、OSの機能を利用する厳密なsleepメソッドではなく、疑似的に動くsleep機能になります。



3.JavaScriptでsleep機能を実装する方法


では実際に、JavaScriptでsleep機能を実装する方法を見ていきましょう。

①timer処理を使う

まずはtimer処理を使って、sleep機能を実装する方法です。

今回は、setIntervalメソッドとsetTimeoutメソッドを利用したコーディング方法を解説します。

setIntervalメソッド

最初に、setIntervalメソッドを使用したsleep機能の実現方法を見ていきましょう。

setIntervalメソッドは、指定ミリ秒間隔でメソッド実行を繰り返し行います。


次のサンプルコードは、1秒間隔でexecutionメソッドを実行し、5秒経過したときに停止します。

//タイムアウト後に実行する関数
let execution = () => console.log(`間隔: ${getDisplayDate()} 秒`)

console.log(`停止前: ${getDisplayDate()} 秒`)
//1秒間隔で、executionメソッドを実行
let intervalId = setInterval(execution, 1000)
//5秒経過したあとに停止
setTimeout(() => clearInterval(intervalId), 5000)

//現在時刻を取得
function getDisplayDate(){
  let date = new Date();
  let Hour = ('0' + date.getHours()).slice(-2)
  let Minute = ('0' + date.getMinutes()).slice(-2)
  let Second = ('0' + date.getSeconds()).slice(-2)
  //HH:MM:SS形式に整形
  return Hour + ':' + Minute + ':' + Second
}

実行結果:

停止前: 07:38:17 秒

間隔: 07:38:18 秒

間隔: 07:38:19 秒

間隔: 07:38:20 秒

間隔: 07:38:21 秒


setIntervalメソッドに1000ミリ秒を指定し、1秒間隔でexecutionメソッドを実行しています。

clearIntervalメソッドでは5000ミリ秒を指定しているので、5秒経過すると、タイマーを停止します。

setTimeoutメソッド

次は、setTimeoutメソッドを使ってsleep機能を実装する方法です。


setTimeoutメソッドに5000ミリ秒を指定しているので、5秒後にexecutionメソッドが実行されます。

//タイムアウト後に実行する関数
let execution = () => console.log(`停止後: ${getDisplayDate()} 秒`)

console.log(`停止前: ${getDisplayDate()} 秒`)
//5秒停止
setTimeout(execution, 5000)

//現在時刻を取得
function getDisplayDate(){
  let date = new Date();
  let Hour = ('0' + date.getHours()).slice(-2)
  let Minute = ('0' + date.getMinutes()).slice(-2)
  let Second = ('0' + date.getSeconds()).slice(-2)

  return Hour + ':' + Minute + ':' + Second
}

実行結果:

停止前: 15:24:19 秒

停止後: 15:24:24 秒


実行結果から、5秒間一時停止しているのがわかりますね。

②jQueryを使う

jQueryとはJavaScriptのライブラリのひとつで、JavaScriptを使いやすく拡張したものです。

このjQueryを使ってsleep機能を実装できます。


サンプルコードで確認しましょう。


main.js

unction wait(sec) {
  // jQueryのDeferredを作成します。
  var objDef = new $.Deferred;

  setTimeout(function () {
    // 5秒後に、resolve()を実行し、Promiseを完了。
    objDef.resolve(sec);
  }, sec*1000);
  return objDef.promise();
};

function SleepMethod(){
  console.log(`停止前: ${getDisplayDate()} 秒`);

  // waitメソッドはPromiseを返すので、doneをメソッド・チェーンが可能。
  wait(5).done(function () {
    console.log(`停止後: ${getDisplayDate()} 秒`);
  });
}

//現在時刻を取得
function getDisplayDate(){
  let date = new Date();
  let Hour = ('0' + date.getHours()).slice(-2)
  let Minute = ('0' + date.getMinutes()).slice(-2)
  let Second = ('0' + date.getSeconds()).slice(-2)
  //HH:MM:SS形式に整形
  return Hour + ':' + Minute + ':' + Second
}

jQueryを使うためには、htmlファイルでjQueryライブラリを読み込む必要があります。

このサンプルコードではCDNを利用してjQueryライブラリを読み込むようにします。


CDNとは、”Content Delivery Network”の略で、インターネット経由でファイルを取得する仕組みです。ファイルをダウンロードする必要がないので、簡単にjQueryを利用することができます。


jQuery公式サイト


2022年11月現在、jQueryの最新バージョンは3.6.1となっており、今回はサイズが軽量の”minified”を選択しました。


公式サイトからURLをコピーし、scriptタグのsrc属性に貼り付けましょう。



index.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>JavaScriptでsleep機能を実装</title>
    <!-- 外部ファイルとしてJavaScriptファイルを読み込む -->
    <script src="main.js"></script>
    <!-- jQueryをCDN経由で利用する-->>
    <script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
  </head>

  <body>
    <h1>JavaScriptでsleep機能を実装</h1>
    <h2>jQueryを使う</h2>
    <button type="button" onclick="SleepMethod()">
      5秒停止します。
    </button>

  </body> 
</html>

ボタンクリック結果:

停止前: 16:41:31 秒

停止後: 16:41:36 秒


サンプルコードのようにwaitメソッドで5秒待機の指定をすると、5秒後にPromiseオブジェクトが返されるため、メソッドチェーンにてdoneメソッドを実行します。

また、doneメソッドに無名関数を与えると、5秒後に実行されます。 

③Promiseを使う

Promiseとは、非同期処理の完了の結果を返すオブジェクトです。

ここでは、Promiseを使ったsleep処理のサンプルコードを見てみましょう。

console.log(`停止前: ${getDisplayDate()} 秒`)
const sleep = waitTime => new Promise( resolve => setTimeout(resolve, waitTime) );
 
sleep( 5000 )
  .then( ()=>{
    // 5秒停止後の処理
    console.log(`停止後: ${getDisplayDate()} 秒`)
  });

//現在時刻を取得
function getDisplayDate(){
  let date = new Date();
  let Hour = ('0' + date.getHours()).slice(-2)
  let Minute = ('0' + date.getMinutes()).slice(-2)
  let Second = ('0' + date.getSeconds()).slice(-2)

  return Hour + ':' + Minute + ':' + Second
}

実行結果:

停止前: 06:55:15 秒

停止後: 06:55:20 秒


resolveメソッドは、処理が完了したときにメッセージを表示する関数で、setTimeoutと組み合わせることでsleep処理を実現しています。

④Generatorを使う

次は、Generatorを使ったsleep機能の実装方法を見てみましょう。

function sleep(ms, generator) {
  setTimeout(() => generator.next(), ms);
}

var main = (function*() {
  console.log(`停止前: ${getDisplayDate()} 秒`);
  yield sleep(5*1000, main);

  console.log(`停止後: ${getDisplayDate()} 秒`);
})();
main.next();

//現在時刻を取得
function getDisplayDate(){
  let date = new Date();
  let Hour = ('0' + date.getHours()).slice(-2)
  let Minute = ('0' + date.getMinutes()).slice(-2)
  let Second = ('0' + date.getSeconds()).slice(-2)

  return Hour + ':' + Minute + ':' + Second
}

実行結果:

停止前: 21:12:24 秒

停止後: 21:12:29 秒


このサンプルコードは、Generatorオブジェクトを再帰的に呼び出して、sleep機能を実装しています。

⑤async/awaitを使う

最後に紹介する方法は、async/awaitを使ったやり方です。

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

async function start() {
  //5秒間sleep
  await sleep(5000);
  console.log(`停止後: ${getDisplayDate()} 秒`);
}

console.log(`停止前: ${getDisplayDate()} 秒`);
start();

//現在時刻を取得
function getDisplayDate(){
  let date = new Date();
  let Hour = ('0' + date.getHours()).slice(-2)
  let Minute = ('0' + date.getMinutes()).slice(-2)
  let Second = ('0' + date.getSeconds()).slice(-2)

  return Hour + ':' + Minute + ':' + Second
}

実行結果:

停止前: 21:28:53 秒

停止後: 21:28:58 秒


async function内で、await演算子を使用し、Promise処理の完了待ちをすることでsleep機能を実現しています。sleep機能を一行で記述できるので、きれいなコードになります。



4.それぞれの方法の違い

ここまで学んだ、それぞれの方法の特徴についてまとめてみます。

各方法の特徴を把握し、用途に合った使い方をしましょう。

方法特徴利用シーン
setIntervalsetIntervalとclearIntervalを組み合わせて
一定時間ごとに処理を実行する
最新情報を定期的に取得する
ニュースサイトの構築 など
setTimeout複数タイマーを指定するとネストが深くなり
可読性が悪くなる
画面表示された数秒後のアラート
表示など、単純なタイマー処理
jQueryjQueryライブラリを使用する別ロジックでもjQueryを
使う場合
Promise複数タイマーでも簡潔に書ける。バージョンES2015が必要連続したsleep処理を
実装するとき など
Generator複数タイマーを直列につなげても簡潔に書ける途中で処理を止めて、止めた
ところから再処理する など
async/await開発環境がバージョンES2017以降であれば、
一行で書くことができる
分岐やループを含むsleep処理を
実装するとき など




5.一行で簡潔に書けるawaitとPromiseの使用がベター


JavaScriptでsleep機能を実装する方法をいくつか紹介してきましたが、ここでおすすめのやり方を紹介します。


JavaScriptの開発環境がバージョンES2017以降に対応しているのであれば、async/awaitを使う方法がベターです。

Promiseによる非同期処理とタイマー処理を組み合わせることで、一行で簡潔に記述することが可能になるので、おすすめと言えます。




※掲載された社名、製品名は、各社の商標及び登録商標です。


この記事をシェア