JavaScript には sleep()
関数がありません。この関数により、コードは実行を再開する前に指定された期間待機します。 JavaScript を待機させる必要がある場合はどうすればよいですか?
各メッセージ間に 1 秒の遅延を設けて、3 つのメッセージを Javascript コンソールに記録するとします。 JavaScript には sleep()
メソッドがないため、次善のメソッド setTimeout()
の使用を試みることができます。
残念ながら、setTimeout()
は、使い方によっては期待どおりに機能しません。おそらく JavaScript ループのある時点でこれを試してみたところ、setTimeout()
がまったく機能しないように見えることがわかりました。
この問題は、実際には独自のルール セットに従って動作する setTimeout()
を sleep()
関数と誤解することで発生します。
この記事では、setTimeout()
の使用方法について説明します。これには、JavaScript に実行を一時停止させ、連続するコード行の間で待機させるスリープ関数を作成する方法も含まれます。
setTimeout()
のドキュメントを見ると、ミリ秒単位の「遅延」パラメータが必要なようです。
元の質問に戻りますが、setTimeout(1000)
を呼び出して、console.log()
関数の呼び出しの間に 1 秒待機しようとしています。
残念ながら、setTimeout()
は次のようには機能しません:
setTimeout(1000) console.log(1) setTimeout(1000) console.log(2) setTimeout(1000) console.log(3) for (let i = 0; i <= 3; i++) { setTimeout(1000) console.log(`#${i}`) }
このコードの結果は、setTimeout()
と同様に完全に遅延しません。存在も同じです。
ドキュメントを振り返ると、最初のパラメータが実際には遅延ではなく関数呼び出しでなければならないことが問題であることがわかります。結局のところ、setTimeout()
は実際には sleep()
メソッドではありません。
コールバック関数を最初のパラメーターとして、必要な遅延を 2 番目のパラメーターとして受け取るようにコードを書き換えます。
setTimeout(() => console.log(1), 1000) setTimeout(() => console.log(2), 1000) setTimeout(() => console.log(3), 1000) for (let i = 0; i <= 3; i++) { setTimeout(() => console.log(`#${i}`), 1000) }
このようにして、3 つの console.log ログ メッセージが、 1000 ミリ秒 (1 秒) の 1 回の遅延では、繰り返される各通話の間に 1 秒の遅延が生じるという理想的な効果ではなく、それらが一緒に表示されます。
この問題の解決方法を説明する前に、setTimeout()
関数を詳しく調べてみましょう。
上の 2 番目のコード スニペットで矢印関数が使用されていることに気づいたかもしれません。これらが必要なのは、タイムアウト後に実行されるコードを実行する匿名コールバック関数を setTimeout()
に渡す必要があるためです。
匿名関数では、タイムアウト後に実行される任意のコードを指定できます。
// 使用箭头语法的匿名回调函数。 setTimeout(() => console.log("你好!"), 1000) // 这等同于使用function关键字 setTimeout(function() { console.log("你好!") }, 1000)
理論的には、最初のパラメーターとして関数を渡し、コールバック関数のパラメーターを渡すだけです。
// 应该能用,但不能用 setTimeout(console.log, 1000, "你好")
人々は文字列を使用してこの問題を解決しましたが、これはお勧めできません。文字列から JavaScript を実行すると、悪意のある者が文字列として挿入された任意のコードを実行できるため、セキュリティに影響を及ぼします。
// 应该没用,但确实有用 setTimeout(`console.log("你好")`, 1000)
では、なぜ最初のコード例で setTimeout()
が失敗するのでしょうか?正しく使用しているようで、毎回 1000ms の遅延が繰り返されます。
その理由は、setTimeout()
が同期コードとして実行され、setTimeout()
への複数の呼び出しがすべて同時に実行されるためです。 setTimeout()
を呼び出すたびに、指定された遅延の後に実行される非同期コードが作成されます。スニペット内のすべての遅延は同じ (1000 ミリ秒) であるため、キューに入れられたすべてのコードは 1 秒の遅延後に同時に実行されます。
前に述べたように、setTimeout()
は実際には sleep()
関数ではなく、後で実行するために非同期コードをキューに入れるだけです。幸いなことに、setTimeout()
を使用して、JavaScript で独自の sleep()
関数を作成することができます。
Promise の関数 async
と await
を使用して、sleep() を書くことができます。
関数。期待どおりに動作します。
ただし、このカスタム sleep()
関数は async
関数からのみ呼び出すことができ、これを await
関数と組み合わせる必要があります。キーワードを併用してください。
このコードは、sleep()
関数の書き方を示しています。
const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay)) const repeatedGreetings = async () => { await sleep(1000) console.log(1) await sleep(1000) console.log(2) await sleep(1000) console.log(3) } repeatedGreetings()
この 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)) async function repeatGreetingsLoop() { for (let i = 0; i <= 5; i++) { await sleep(1000) console.log(`Hello #${i}`) } } repeatGreetingsLoop()
这是一个简单的使用增加超时的代码片段:
for (let i = 0; i <= 5; i++) { setTimeout(() => console.log(`Hello #${i}`), 1000 * i) }
我更喜欢后一种语法,特别是在循环中使用。
JavaScript可能没有 sleep()
或 wait()
函数,但是使用内置的 setTimeout()
函数很容易创建一个JavaScript,只要你谨慎使用它即可。
就其本身而言,setTimeout()
不能用作 sleep()
函数,但是你可以使用 async
和 await
创建自定义JavaScript sleep()
函数。
采用不同的方法,可以将交错的(增加的)超时传递给 setTimeout()
来模拟 sleep()
函数。之所以可行,是因为所有对setTimeout()
的调用都是同步执行的,就像JavaScript通常一样。
希望这可以帮助你在代码中引入一些延迟——仅使用原始JavaScript,而无需外部库或框架。
祝您编码愉快!
英文原文地址:https://medium.com/dev-genius/how-to-make-javascript-sleep-or-wait-d95d33c99909
作者:Dr. Derek Austin
更多编程相关知识,请访问:编程视频!!
以上がJavaScriptを使用したスリープまたはウェイトの実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。