今回は、一定時間経過後に任意のプログラムを実行させるsleep関数の作り方について学習を進めていきましょう!
「任意の時間が経過後に処理を実行させたい場合はどうすれば良いの?」
「sleep関数を自作する方法が知りたい」
「Node.jsモジュールのsleep関数はどう使えばいい?」
このような内容も含めて、本記事では以下のような構成で解説していきます!
【基礎】「sleep関数」の作り方
【実践】Promiseによるsleep関数
【実践】async / awaitによるsleep関数
【まとめ】sleepモジュールの使い方
この記事で、sleep関数の作り方をしっかり学習してスキルアップを目指していきましょう!
「sleep関数」とは?
今回は、指定した時間が経過したあとにプログラムの処理を実行するようなケースを想定したsleep関数を自作していきましょう。
例えば、Aという処理を実行したあとに数秒間待ってから次の処理を実行したいようなケースや、デバッグなどで処理の流れを確認したいような時に有効です。
このような処理を実現する関数(sleep)は一般的なプログラム言語だと標準で提供されていますが、Node.jsには実装されていません。
もちろん、同じ用途で使えるメソッドはNode.jsにもあるので、これらを活用しながらsleep関数を作っていきますのでぜひ参考にしてみてください。
「sleep関数」の作り方
この章では、もっとも基本的なsleep関数の作り方についてご紹介していきます。
主に、setTimeout()を活用した自作関数の作り方について学んでいきます。
setTimeout()を使ってsleep関数を作る
まずは、setTimeout()のおさらいをしておきましょう。
setTimeout()は、指定したミリ秒の間だけ処理を遅らせて実行することができるメソッドです。
基本的な構文は以下の通りです。
setTimeout(実行させたい関数, 待ち時間)
待ち時間はミリ秒を指定するという点に注意しておきましょう。
例えば、3秒後にアラートを表示させるには次のように記述します。
function alertMsg(){ alert("3秒経過しました"); } setTimeout(alertMsg, 3000);
第1引数に指定した関数は、設定した時間経過後に実行するのが分かりますね。
実は、今回やりたいsleep関数はこのsetTimeout()を使えばそのまま同じようなことが実現できます。
ただし、せっかくなのでsleepという名称の関数にラップしておきましょう。
function sleep(waitSec, callback) { setTimeout(callback, waitSec); }
実際の使い方については次の章で解説していきます。
また、setTimeout()についてもっと詳しく知りたい方は、次の記事で体系的にまとめているのでぜひ参考にしてみてください。
sleep関数の実行方法
それでは、先ほど作成したsleep関数を実行してみましょう。
例えば、3秒経過後にコンソールへメッセージを表示するには次のように記述します。
console.log('スタート'); sleep(3000, function() { console.log('3秒経過しました'); });
注意が必要なのは、このsleep関数内でさらにsleep関数を実行して階層構造を作ってしまうことです。
console.log('スタート'); sleep(3000, function() { console.log('3秒経過しました'); sleep(2000, function() { console.log('2秒経過しました'); sleep(5000, function() { console.log('5秒経過しました'); }); }); });
このように記述すると設定した時間通りに処理が実行できるわけですが、プログラムが見づらくなり管理ができなくなってきます。
そこで、sleep関数で複雑な処理をしたい場合は次の章以降で解説するメソッドを利用していきましょう!
Promiseによるsleep関数の作り方
Promiseは非同期処理を効率よく記述できるメソッドですが、sleep関数を複数実行する際にも有効な手段と言えます。
まずは、先ほどsetTimeout()を利用して作成したsleep関数をPromiseを利用して作り直すと次のようになります。
function sleep(waitSec) { return new Promise(function (resolve) { setTimeout(function() { resolve() }, waitSec); }); }
新たにPromiseオブジェクトを作り、その中でsetTimeout()を実行していますね。
このように記述することで、then()を使った呼び出しができるようになるので複数のsleep関数を実行しても階層が深くなることはありません。
sleep(2000) .then(function() { console.log('2秒経過しました'); return sleep(1000); }) .then(function() { console.log('1秒経過しました'); return sleep(3000); }) .then(function() { console.log('3秒経過しました'); })
複数繋げる場合は、1つずつのthen()の中でsleep関数をreturnすることを忘れないようにしましょう。
また、基本的なPromise処理についてまだ不安のある方は、次の記事で体系的にまとめているので参考にしてみてください。
async/awiatによるsleep関数の作り方
今度は、新しく導入されたasync / awaitによるsleep関数を作ってみましょう。
async / awaitを使うと、前章のthen()を使ったメソッドチェーンよりもさらに効率よく複数のsleep関数を記述できるようになります。
作り方は、これまでと同様にPromiseオブジェクトを作成しておきます。
function sleep(waitSec) { return new Promise(function (resolve) { setTimeout(function() { resolve() }, waitSec); }); }
あとは、asyncで設定した関数内にawaitを使ったPromise処理を記述するだけです。
async function start() { await sleep(2000); console.log('2秒経過しました'); await sleep(1000); console.log('1秒経過しました'); await sleep(3000); console.log('3秒経過しました'); } start();
コードがスッキリして直感的に理解しやすくなりましたね。
ちなみに、Node.js用のasyncパッケージを活用したプログラミング方法もあるので、次の記事をぜひ参考にしてみてください。
sleepモジュールの使い方
この章では、Node.jsのモジュールとして提供されているsleep関数の使い方について見ていきましょう!
まずは、npmを使ってsleepモジュールをインストールします。
$ npm install sleep
次に、require()でNode.jsから利用できるようにします。
var sleep = require('sleep');
これで、sleep関数が使えるようになりました。
例えば、3秒後にメッセージをコンソールへ出力するには次のように実行します。
sleep.sleep(3); console.log('3sec');
sleepモジュールでは、引数に秒数を指定することでその時間分だけ待ち時間になります。
また、「msleep()」メソッドを利用するとミリ秒単位で待ち時間を指定することも可能です。
まとめ
今回は、Node.jsで一定時間経過後に処理を実行するsleep関数の自作方法について学習をしました。
最後に、もう一度ポイントをおさらいしておきましょう!
・setTimeout()を使うと階層が複雑になるにつれてバグを引き起こしやすくなる
・Promise処理を活用するとthen()によるメソッドチェーンで効率よく記述できる
・async / awaitが利用できればもっとも簡潔に記述することができる
上記内容を踏まえて、ぜひ自分でもプログラミングに取り入れて活用できるように頑張りましょう!