TypeScript実践力を身につける!コードスニペットで学ぶ型付けとインターフェース
- 1. sleep機能とは?
- 2. JavaScriptにはsleepメソッドがない
- 3.JavaScriptでsleep機能を実装する方法
- 4.それぞれの方法の違い
- 5.一行で簡潔に書けるawaitとPromiseの使用がベター
今回は、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を利用することができます。
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.それぞれの方法の違い
ここまで学んだ、それぞれの方法の特徴についてまとめてみます。
各方法の特徴を把握し、用途に合った使い方をしましょう。
方法 | 特徴 | 利用シーン |
setInterval | setIntervalとclearIntervalを組み合わせて 一定時間ごとに処理を実行する | 最新情報を定期的に取得する ニュースサイトの構築 など |
setTimeout | 複数タイマーを指定するとネストが深くなり 可読性が悪くなる | 画面表示された数秒後のアラート 表示など、単純なタイマー処理 |
jQuery | jQueryライブラリを使用する | 別ロジックでもjQueryを 使う場合 |
Promise | 複数タイマーでも簡潔に書ける。バージョンES2015が必要 | 連続したsleep処理を 実装するとき など |
Generator | 複数タイマーを直列につなげても簡潔に書ける | 途中で処理を止めて、止めた ところから再処理する など |
async/await | 開発環境がバージョンES2017以降であれば、 一行で書くことができる | 分岐やループを含むsleep処理を 実装するとき など |
5.一行で簡潔に書けるawaitとPromiseの使用がベター
JavaScriptでsleep機能を実装する方法をいくつか紹介してきましたが、ここでおすすめのやり方を紹介します。
JavaScriptの開発環境がバージョンES2017以降に対応しているのであれば、async/awaitを使う方法がベターです。
Promiseによる非同期処理とタイマー処理を組み合わせることで、一行で簡潔に記述することが可能になるので、おすすめと言えます。
※掲載された社名、製品名は、各社の商標及び登録商標です。