JavaScript をスリープまたは待機させる方法

JavaScript をスリープまたは待機させる方法

概要

JavaScript には、実行を再開する前に指定された時間だけコードを待機させる sleep() 関数がありません。 JavaScript を待機させる必要がある場合、どのようにすればよいでしょうか?

各メッセージの間に 1 秒の遅延を設けて、3 つのメッセージを Javascript コンソールに記録するとします。 JavaScript には sleep() メソッドがないので、次善策として setTimeout() メソッドを使用してみてください。

残念ながら、setTimeout() は、使用方法によっては期待どおりに動作しません。おそらく、JavaScript ループのどこかの時点でこれを試してみて、setTimeout() が単に機能しないように見えることに気づいたでしょう。

この問題は、setTimeout() が sleep() 関数であると誤解されることから発生しますが、実際には setTimeout() は独自のルールに従って動作します。

setTimeout() のドキュメントを見ると、ミリ秒単位の「遅延」パラメータが必要であるようです。

元の問題に戻ると、console.log() 関数への 2 回の呼び出しの間に 1 秒待機するために setTimeout(1000) を呼び出そうとしました。

残念ながら、setTimeout() は次のようには動作しません。

タイムアウトを設定します(1000)
コンソール.log(1)
タイムアウトを設定します(1000)
コンソール.log(2)
タイムアウトを設定します(1000)
コンソール.log(3)

(i = 0; i <= 3; i++ とします) {
  タイムアウトを設定します(1000)
  コンソールログ(`#${i}`)
}

このコードでは、setTimeout() が存在しなかったかのように、遅延はまったく発生しません。

ドキュメントをもう一度見てみると、最初の引数は遅延ではなく関数呼び出しである必要があるという問題が分かります。結局のところ、setTimeout() は実際には sleep() メソッドではありません。

コードを書き直して、最初の引数としてコールバック関数を受け取り、2 番目の引数として必要な遅延を受け取ります。

setTimeout(() => console.log(1), 1000)
setTimeout(() => console.log(2), 1000)
setTimeout(() => console.log(3), 1000)

(i = 0; i <= 3; i++ とします) {
  setTimeout(() => console.log(`#${i}`), 1000)
}

この方法では、繰り返される各呼び出しの間に 1 秒の遅延を設けるという理想的な効果ではなく、1000 ミリ秒 (1 秒) の単一の遅延の後に、3 つの console.log 呼び出しのログ情報が一緒に表示されます。

この問題を解決する方法について説明する前に、setTimeout() 関数を詳しく見てみましょう。

setTimeout() の確認

上記の 2 番目のコード スニペットで矢印関数が使用されていることに気づいたかもしれません。これらが必要なのは、タイムアウト後に実行されるコードを実行する匿名コールバック関数を setTimeout() に渡す必要があるためです。

匿名関数では、タイムアウト期間後に実行される任意のコードを指定できます。

// 矢印構文を使用した匿名コールバック関数。
setTimeout(() => console.log("こんにちは!"), 1000)
// これは関数キーワード setTimeout(function() { console.log("Hello!") }, 1000) を使用するのと同じです

理論的には、関数を最初の引数として渡し、コールバックの引数を残りの引数として渡すこともできますが、これは私の環境では正しく動作しないようです。

// 動作するはずですが、動作しません setTimeout(console.log, 1000, "Hello")

この問題を解決するために文字列を使用する人もいますが、これはお勧めできません。文字列から JavaScript を実行すると、悪意のあるユーザーが文字列として挿入された任意のコードを実行できるため、セキュリティに影響を及ぼします。

// 動作するはずはないが、動作する setTimeout(`console.log("Hello")`, 1000)

では、最初のコード例で setTimeout() が失敗したのはなぜでしょうか?正しく使用しているようで、1000 ミリ秒の遅延が毎回繰り返されます。

その理由は、setTimeout() が同期コードとして実行され、setTimeout() への複数の呼び出しが同時に実行されるためです。 setTimeout() を呼び出すたびに、指定された遅延後に実行される非同期コードが作成されます。コード スニペット内の各遅延は同じ (1000 ミリ秒) なので、キューに入れられたすべてのコードは 1 秒の遅延後に同時に実行されます。

前述したように、setTimeout() は実際には sleep() 関数ではなく、単に非同期コードをキューに入れて後で実行するだけです。幸いなことに、JavaScript で setTimeout() を使用して独自の sleep() 関数を作成できます。

スリープ関数の書き方

Promise、async、await の力を利用すると、期待どおりに動作する sleep() 関数を作成できます。

ただし、このカスタム sleep() 関数は非同期関数内からのみ呼び出すことができ、await キーワードとともに使用する必要があります。

このコードは sleep() 関数の書き方を示しています。

const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay))

const 繰り返し挨拶 = async() => {
  スリープを待つ(1000)
  コンソール.log(1)
  スリープを待つ(1000)
  コンソール.log(2)
  スリープを待つ(1000)
  コンソール.log(3)
}
繰り返し挨拶()

この JavaScript sleep() 関数は、await によって Promise が解決されるまでコードの同期実行が一時停止されるため、期待どおりに動作します。

シンプルな選択

あるいは、setTimeout() の最初の呼び出しで増分タイムアウトを指定することもできます。

次のコードは前の例と同等です。

setTimeout(() => console.log(1), 1000)
setTimeout(() => console.log(2), 2000)
setTimeout(() => console.log(3), 3000)

タイムアウトの増加を使用すると、コードが同時に実行されるため、同期コード実行の 1、2、3 秒後に指定されたコールバック関数が実行されることになります。

ループで実行されますか?

ご想像のとおり、JavaScript の実行を一時停止する両方のオプションは、ループ内では正常に機能します。 2つの簡単な例を見てみましょう。

以下は、カスタム sleep() 関数を使用したコード スニペットです。

const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay))

非同期関数repeatGreetingsLoop() {
  (i = 0; i <= 5; i++ とします) {
      スリープを待つ(1000)
    console.log(`こんにちは #${i}`)
    }
}
繰り返し挨拶ループ()

以下は、タイムアウトを増やす簡単なコード スニペットです。

(i = 0; i <= 5; i++ とします) {
  setTimeout(() => console.log(`Hello #${i}`), 1000 * i)
}

特にループで使用する場合は、後者の構文を好みます。

要約する

JavaScript には sleep() 関数や wait() 関数はありませんが、注意して使用すれば、組み込みの setTimeout() 関数を使用して簡単に作成できます。

setTimeout() を単独で sleep() 関数として使用することはできませんが、async と await を使用してカスタム JavaScript sleep() 関数を作成できます。

別のアプローチとして、段階的に増加するタイムアウトを setTimeout() に渡して、sleep() 関数をエミュレートすることもできます。これが機能するのは、JavaScript が通常行うように、setTimeout() へのすべての呼び出しが同期的に実行されるためです。

外部ライブラリやフレームワークを必要とせず、Vanilla JavaScript のみを使用して、コードにレイテンシを導入するのに役立つことを願っています。

上記は、JavaScript をスリープまたは待機させる方法の詳細です。JavaScript をスリープまたは待機させる方法についての詳細は、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • JavaScript における async/await の使い方と理解について
  • spin.js を使用して待機効果を生成する (js 待機効果)
  • JSはモバイル認証コードを設定し、コードを実装するために60秒間待機します
  • カスタム表示読み込み待機画像プラグインの JS 実装 (loading.gif)
  • 独自のJavaScriptフロントエンド待機コントロールを作成する
  • JavaScript カスタム待機関数の例の分析
  • JavaScriptのスリープ機能を提供する自己コンパイルJSエンジン
  • JavaScript でスリープ関数を使用する一般的な方法の詳細な説明
  • js でカスタム メソッドを使用して数秒間スリープする方法
  • JavaScript にはスリープ機能がありません。この機能を実装するにはどうすればよいでしょうか?

<<:  Linux で killall コマンドを使用してプロセスを終了する 8 つの例

>>:  UbuntuはPythonスクリプトのサンプルコードを定期的に実行する

推薦する

JavaScript ベースのシンプルな計算機の実装

この記事では、参考までに、簡単な計算機を実装するためのJavaScriptの具体的なコードを紹介しま...

jsを使用してシンプルな弾幕スクリーンシステムを実装する

この記事では、弾幕効果を実現するためのネイティブjsの具体的なコードを参考までに共有します。具体的な...

Web 標準アプリケーション: Tencent QQ ホームページの再設計

Tencent QQのホームページがリニューアルされ、Webフロントエンド開発がますます注目を集めて...

Vue v-model 関連の知識のまとめ

​v-model は、入力とフォーム データ間、または 2 つのコンポーネント間の双方向データ バイ...

CSSで検索ボックスを非表示にする機能を実装します(アニメーション順方向と逆方向のシーケンス)

上部のメニュー バーに検索ボックスを配置するのは一般的なシナリオですが、検索機能がそれほど頻繁に使用...

Dockerに関するよくある質問

Docker はポートを IPv6 にのみマッピングし、IPv4 にはマッピングしません。 dock...

Mysql は最大接続数を表示し、最大接続数を変更します

MySQL 最大接続数の表示と最大接続数の変更1. 最大接続数を確認する '%max_con...

ボリュームを使用してホストと Docker コンテナ間でファイルを転送する方法

以前、Docker コンテナとローカル マシン間のファイル転送に関する記事を書きました。しかし、この...

MySql ストレージ エンジンとインデックスに関する知識のまとめ

ストレージエンジンデータベース ストレージ エンジンとは何ですか?データベース エンジンは、データベ...

MySQL の低速クエリの最適化: 理論と実践からの制限の利点

多くの場合、クエリの結果は最大で 1 つのデータ レコードになることが予想されます。この場合、制限 ...

SQL インジェクションのある Web サイトを見つける方法 (必読)

方法 1: Google の詳細検索を使用します。たとえば、次に示すように.asp?id=9などの ...

CSS カウンターとコンテンツの概要

コンテンツ プロパティは CSS 2.1 で導入され、:before および :after 疑似要素...

Dockerでデータディレクトリを移行する方法

目次ディスク使用量の表示ディスク クリーンアップ (軽々しく使用しないでください)データの移行ディス...

Ubuntu16.04にclionをインストールするプロセス全体と手順の詳細な説明

CLion のプロセス全体を最初から説明します。CLion は、JetBrains がリリースした新...

Reactはページの透かし効果の全プロセスを実現します

目次序文1. 使用例2. 実施プロセス3. コンポーネントコード要約する序文1. cavans では...