「遅延実行」とは何をしたいテクニックか
「遅延実行」は、その名の通り
「今すぐではなく、少し時間をおいてから処理を実行する」ためのテクニックです。
例えば、次のような場面をイメージしてください。
ユーザーがボタンを押してから 1 秒後にメッセージを出したい。
画面描画が落ち着いてから重い処理を走らせたい。
連続で呼ばれる処理を、少し遅らせてまとめて実行したい(デバウンスの土台)。
こういうときに、「遅延して実行する仕組み」をユーティリティとして持っておくと、
コードの見通しが良くなり、同じパターンを何度もきれいに再利用できます。
JavaScript の基本的な遅延実行:setTimeout
JavaScript で「一定時間後に処理を実行する」基本の仕組みは setTimeout です。
setTimeout(() => {
console.log("1秒後に実行されました");
}, 1000); // 1000ミリ秒 = 1秒
JavaScriptこのコードは、「1秒後にこの関数を実行してね」という予約をしています。setTimeout 自体はすぐに返り、指定した時間が経ったあとでコールバックが呼ばれます。
ポイントは、「今すぐ実行する」のではなく「後で実行するように登録する」ことです。
これが「遅延実行」の一番シンプルな形です。
ユーティリティとしての遅延実行関数 delay
毎回 setTimeout を直接書いてもいいのですが、
業務コードでは「関数をラップして“遅れて実行される版”を返す」ユーティリティにしておくと、とても使いやすくなります。
シンプルな delay 実装
まずは基本形から。
function delay(fn, ms) {
return function delayed(...args) {
setTimeout(() => {
fn(...args);
}, ms);
};
}
JavaScriptこの delay は、「元の関数 fn を、ms ミリ秒遅れて実行する関数」に変換してくれます。
使い方はこうです。
function greet(name) {
console.log(`こんにちは、${name} さん`);
}
const greetLater = delay(greet, 1000);
greetLater("太郎"); // 1秒後に「こんにちは、太郎 さん」と表示される
JavaScriptここで重要なのは、「greetLater を呼んだ瞬間には何も起きず、“予約だけされる”」という点です。
実際の処理は、指定した時間が経ってから実行されます。
this を保ったまま遅延実行する
クラスやオブジェクトのメソッドを遅延実行したいときは、this を正しく保つことが大事です。
そのために apply や call を使います。
function delayWithThis(fn, ms) {
return function delayed(...args) {
const context = this;
setTimeout(() => {
fn.apply(context, args);
}, ms);
};
}
JavaScript使い方の例です。
const user = {
name: "山田",
sayHello() {
console.log(`こんにちは、${this.name} です`);
},
};
user.sayHelloLater = delayWithThis(user.sayHello, 500);
user.sayHelloLater(); // 0.5秒後に「こんにちは、山田 です」
JavaScriptここでの深掘りポイントは、「this を失わないように fn.apply(context, args) としている」ことです。
単に fn(...args) と書くと、this が undefined になってしまい、メソッド内で this.name が使えなくなります。
Promise ベースの遅延実行 delayAsync
「一定時間待ってから次の処理をしたい」というとき、async/await と組み合わせて使える Promise 版の遅延ユーティリティもよく使います。
function delayAsync(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
JavaScript使い方はこうです。
async function main() {
console.log("開始");
await delayAsync(1000); // 1秒待つ
console.log("1秒後に実行");
}
main();
JavaScriptここでの重要ポイントは、「await delayAsync(ms) と書くことで、“時間待ち”を普通の処理のように書ける」ことです。
これを使うと、例えば「API を叩いてから 500ms 待ってローディングを消す」といった処理が、とても読みやすく書けます。
遅延実行ユーティリティと debounce / throttle へのつながり
遅延実行は、それ単体でも便利ですが、
「高頻度イベントを制御するテクニック」の土台にもなります。
入力が止まってから 300ms 後にだけ検索処理を走らせる(debounce)
スクロール中、一定間隔ごとにだけ処理を走らせる(throttle)
こういったユーティリティは、内部で setTimeout を使って「遅延して実行する」仕組みを組み立てています。
まずは今回のようなシンプルな delay や delayAsync を自分で書いてみて、
「処理を“今すぐ”ではなく“あとで”に回す感覚」をつかむと、
その先の debounce / throttle も理解しやすくなります。
実務での具体的な利用イメージ
例えば、ボタンを押したあとに「処理中…」と表示し、
1 秒後に「完了しました」と表示したいケースを考えてみます。
const showDoneLater = delay(() => {
console.log("完了しました");
}, 1000);
function onClick() {
console.log("処理中…");
showDoneLater();
}
onClick();
// すぐに「処理中…」
// 1秒後に「完了しました」
JavaScriptあるいは、async/await を使って「待つ」ことを明示的に書くこともできます。
async function runTask() {
console.log("処理開始");
await delayAsync(1500);
console.log("1.5秒後に次の処理");
}
runTask();
JavaScriptこうやって、「時間をずらして実行する」という発想をユーティリティとして持っておくと、
アニメーション、ローディング表示、API 呼び出しの間隔調整など、
実務でよく出てくる“ちょっとした時間調整”が、きれいなコードで書けるようになります。
