テキストを入力するだけでメッセージ動画が作れるサービスTeloppyを運営しております!
sleepとは?
phpの例で言うと
sleep(1);
echo "1秒経過"
sleep(1);
echo "2秒経過"
こんな感じでsleepで指定した秒数待った後に処理ができるようになるという便利な関数で様々な言語で使われています。javascriptにも似たような関数でsetTimeoutがありますが、setTimeoutは非同期関数なので上の処理を実現させるためには
setTimeout(() => {
console.log("1秒経過");
setTimeout(() => {
console.log("2秒経過");
}, 1000);
}, 1000);
このような記述になり、見ずらくて何してるかあまり分からないコードになります。俗に言うコールバック地獄ですね。
Javascriptでは同期処理を実現させるためのawait/async、Promiseが存在しますが、使えるようになるにはある程度勉強しなければなりません。
なので、今回は「複雑なことは覚えたくないけど、sleepは使いたい」人向けの記事になります
手順
まず、何も考えず無心でこれをコピペします。(※スコープには注意)
const sleep = (time) => new Promise((resolve) => setTimeout(resolve, time));//timeはミリ秒
そしてsleepを使いたい関数のfunctionの前に無心で"async"という文字を入れます。
async function hogehoge(){}
のようasyncを入れたらあとは、sleepを呼び出すだけですがsleepを呼び出す際にもまた無心で"await"という文字を入れておきます。これで
const sleep = (time) => new Promise((r) => setTimeout(r, time));//timeはミリ秒
async function hogehoge(){
await sleep(1000);
console.log("1秒経過");
await sleep(1000);
console.log("2秒経過");
}
hogehoge();
のようにsleepを呼び出すことができます!
使用する時の例
sleep関数を使いたい関数の前にとにかく"async"という単語をいれればよいのでよく使われるようなwindow.onloadの中で使う場合の例で言うと
window.onload = async()=>{
await sleep(1000);
console.log("1秒経過")
await sleep(1000);
console.log("2秒経過")
}
のような形で使います。
jqueryの場合は
$(window).on("load",async()=>{
await sleep(1000);
console.log("1秒経過");
await sleep(1000);
console.log("2秒経過");
})
こうですね。
またいちいち関数を宣言せずに処理を実行したい場合は即時関数で
(async()=>{
await sleep(1000);
console.log("1秒経過");
await sleep(1000);
console.log("2秒経過");
})();
こんな感じで使えます。
また当然のことですが、sleepを使った後の処理は指定の秒数待たないと処理が進みません。
window.onload = async()=>{
await sleep(1000);
//1秒後にやりたかった処理
hogehoge();
//1秒待つ必要のなかった処理
gehogeho();
}
このようにhogehoge()は1秒後にやりたかったけど、gehogeho()は1秒待ちたくなかったという場合でもgehogeho()は1秒後に実行されてしまいます。
このような場合はwindow.onloadのfunctionにasyncをつけるのではなく別の関数を用意してasyncをつけます。
window.onload = () => {
async function useSleep(){
await sleep(1000);
//1秒後にやりたかった処理
hogehoge();
}
function dontUseSleep(){
//1秒待つ必要のない処理
gehogeho();
}
useSleep();
dontUseSleep();
}
こうして分けてやると、hogehoge()だけが1秒後に実行されることになります。もっと省略した書き方をすると
window.onload = () => {
(async(){
await sleep(1000);
//1秒後にやりたかった処理
hogehoge();
})();
//1秒待つ必要のない処理
gehogeho();
}
こんな感じです。
最後に
今回使った"async"、"await"はES7(2017)以降でないと動かず、古いブラウザだとエラーになってしまうので古いブラウザのサポートも必要な場合はbabelなどでトランスパイルする必要があります。
ちなみにTypescriptで使いたい場合は
const sleep= (time: number) => new Promise<void>((r) => setTimeout(r, time));
こうです。