[JavaScript] sleep(setTimeout) を Promise化する

2017.10.24

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

おばんです、ダイエットが捗らない田中です。

さて、今回は sleepPromise についてちょっとしたTipsをまとめます。 sleep は非同期処理を擬似的に作り出す時などに有用で、 Promise で扱いたいシーンがたまにあるので紹介します。

setTimeout

JavaScriptには処理を一時停止させる sleep 関数が存在しません。処理を一時停止させたり、待ちを発生させたい場合は setTimeout 関数を利用して実現する方法があります。

const printHoge = () => {
	console.log('Hoge')
}

setTimeout(printHoge, 5000)

// Hoge <- 5秒後にコンソールに出力される

sleep(setTimeout) を Promise化する

連続した非同期処理を書くときによく使う言語機能として Promise があります。

sleep は非同期処理を擬似的に作り出す時などに有用で、 Promise で扱いたいシーンがたまにあるので紹介します。

const printHoge = () => {
	console.log('Hoge')
}

const sleep = (waitSeconds, someFunction) => {
	return new Promise(resolve => {
		setTimeout(() => {
			resolve(someFunction())
		}, waitSeconds * 1000)
	})	
}

sleep(5, printHoge)

// Hoge <- 5秒後にコンソールに出力される

まとめ

実コードの中でこれを利用するとすればフロントエンドか、ちょっとした非同期処理のテストを書くときなどがあるかもしれません。

上記で紹介したコードは、引数の someFunction に何も入れなかった場合に正常動作しないので、バリデーションをかけるか、引数にセットされていなかった場合は処理をしないなどの対応をする必要があります。

参考・関連にも記載していますが、JavaScriptの非同期処理にまつわる処理を説明したリファレンスを見にいくと、今回紹介したコードに近いものが載っているのでそこも見てみてください。

もっとシンプルなsleepを作る

(※2017/10/26追記)

先に書いたコード例は「関数の遅延実行を行う」ための sleep でした。命名があまり適切でない問題があります、 delayRun などの名前のほうが適切だったかもしれません。

const printHoge = () => {
	console.log('Hoge')
}

const delayRun = (waitSeconds, someFunction) => {
	return new Promise(resolve => {
		setTimeout(() => {
			resolve(someFunction())
		}, waitSeconds)
	})	
}

delayRun(5, printHoge)

sleep という命名から純粋に「待たせる」意味を持たせる場合、以下のようなコードの方が適切です。

const printHoge = () => {
	console.log('Hoge')
}

const sleep = (waitSeconds) => {
    return new Promise(resolve => {
        setTimeout(() => {
			resolve()
		}, waitSeconds * 1000)
    })
}

sleep(5)
    .then(() => {
        printHoge()
    })
    .catch((error) => {
        console.log(error)
    })

ちなみにasync/awaitでこの sleep を扱う場合はこうです。

(async () => {
    await sleep(5)
    printHoge()
})().catch((error) => { console.log(error) })

参考・関連