目次
1.スリープ機能とは?
sleep は関数です。その関数は、プログラムを指定された時間一時停止させることであり、時間を遅らせる効果があります。
公式紹介: sleep は、時間を遅らせる関数です. プログラムは一定時間停止し、実行中に割り込み例外がスローされます. この関数を使用する前に、これをキャプチャして処理する必要があります.
例えば:
console.log('1');
sleep(2000);
console.log('2');
コンソールが数値 1 を出力した後、2 秒間隔で数値 2 を出力します。
もちろん、js には sleep メソッドがないため、上記のコードは実行できません。
そこで、この記事では主に js でスリープを実装する方法をいくつか紹介します。
2.なぜ睡眠を使うのですか?
これを見て、なぜスリープを使用するのか、setTimeout を使用して上記の例を実現できるのかと尋ねる人もいます。
setTimeout はコールバック関数を介してタイミング タスクを実装するため、マルチタスク シナリオではコールバックのネストが発生します。
console.time('runTime:');
setTimeout(() => {
console.log('1');
setTimeout(() => {
console.log('2')
setTimeout(() => {
console.log('3')
console.timeEnd('runTime:');
}, 2000);
}, 3000);
}, 2000);
//结果:
//1
//2
//3
//runTime:: 7017.87890625 ms
上記のメソッドにはコールバックのネストの問題があります. sleep 関数を使用することで、上記の例をより便利かつエレガントに実装できることを願っています.
3.睡眠を実現する
次に、いくつかの異なるメソッドを使用して sleep メソッドを実装します。
-
日付に基づく実装
無限ループによるコード実行を防ぎ、タイムアウトするかどうかを確認し続けます。
function sleep(time){ var timeStamp = new Date().getTime(); var endTime = timeStamp + time; while(true){ if (new Date().getTime() > endTime){ return; } } } console.time('runTime:'); sleep(2000); console.log('1'); sleep(3000); console.log('2'); sleep(2000); console.log('3'); console.timeEnd('runTime:'); // 1 // 2 // 3 // runTime:: 7004.301ms
欠点:
上記のコードはスレッドをスリープさせませんが、CPU が高負荷の計算によって他のタスクを処理する時間がなくなります。
これの欠点は、dom レンダリングを含む他のすべてのタスクがスリープ プロセス中に中断されることです。
したがって、プログラムはスリープ プロセス中に一時停止したアニメーションの状態になり、他のタスクを実行しません。
-
約束ベースの睡眠
Pure Promise は、以前の垂直の入れ子を水平の入れ子に変更するだけです。
function sleep(time){ return new Promise(function(resolve){ setTimeout(resolve, time); }); } console.time('runTime:'); console.log('1'); sleep(1000).then(function(){ console.log('2'); sleep(2000).then(function(){ console.log('3'); console.timeEnd('runTime:'); }); }); console.log('a'); // 1 // a // 2 // 3 // runTime:: 3013.476ms
これは実際には、以前の setTimeout のネストと何ら変わりはなく、醜いものでもあります。
ES6 の Generator 関数を使用して上記の例を書き直して、もう一度最適化しましょう。
-
Generator 関数に基づくスリープ
Generator 関数を使用してスリープを実行し、co を使用して自己実行を実行します。
var co = require('co'); function sleep(time){ return new Promise(function(resolve){ setTimeout(resolve, time); }); } var run = function* (){ console.time('runTime:'); console.log('1'); yield sleep(2000); console.log('2'); yield sleep(1000); console.log('3'); console.timeEnd('runTime:'); } co(run); console.log('a'); // 1 // a // 2 // 3 // runTime:: 3004.935ms
コード全体に入れ子の関係がないように見え、実行中にアニメーションが中断されることはなく、他のタスクの実行を妨げないことがわかります。
しかし、共同実行者への追加の参照があるため、まだ欠陥があります。
-
非同期関数に基づくスリープ
async 関数の最大の特徴は独自のエグゼキュータであるため、co なしでスリープを実装できます。
function sleep(time){ return new Promise((resolve) => setTimeout(resolve, time)); } async function run(){ console.time('runTime:'); console.log('1'); await sleep(2000); console.log('2'); await sleep(1000); console.log('3'); console.timeEnd('runTime:'); } run(); console.log('a'); // 1 // a // 2 // 3 // runTime:: 3009.984ms