検索
ホームページウェブフロントエンドjsチュートリアルJavaScript 開発者が知っておくべき setTimeout の秘密

Timer

setTimeout

は、指定したミリ秒後に関数を呼び出したり、式を計算したりするためによく使用されます。

構文:

setTimeout(code, millisec, args);



注: コードが文字列の場合、コードを実行するために

eval()

メソッドを実行するのと同じです。

もちろん、この記事では

setTimeout

の使用方法を説明するだけでなく、それがどのように実行されるかも理解します。

1. setTimeout

の原理 まずコードの一部を見てみましょう:

var start = new Date(); 
var end = 0; 
setTimeout(function() {  console.log(new Date() - start); }, 500); 
while (new Date() - start <= 1000) {}

上記のコードでは、

setTimeout

タイマーが定義されており、遅延時間は 500 ミリ秒です。

印刷結果は500だと思いますか

しかし、事実はあなたの予想を超えており、印刷結果は次のようになります(印刷すると異なるかもしれませんが、間違いなく1000ミリ秒を超えるでしょう):

JavaScript 開発者が知っておくべき setTimeout の秘密

どうしてですか?その理由は、JavaScript が単一スレッドで実行されるためです。つまり、どの時点においても、JavaScript プログラムを実行するスレッドは 1 つだけであり、複数のコードを同時に実行することはできません。

ブラウザーでの JavaScript を見てみましょう。

ブラウザのカーネルはマルチスレッドであり、カーネルの制御下で相互に連携して、ブラウザには少なくとも 3 つの常駐スレッド (JavaScript エンジン スレッド、GUI レンダリング スレッド、ブラウザ イベント トリガー スレッド) が実装されています。

JavaScript引擎

は、イベント駆動型のシングルスレッド実行に基づいています。JavaScript エンジンは、タスク キュー内のタスクの到着を待ってから、それらを処理します。ブラウザーでは、常に 1 つの JavaScript スレッドのみが JavaScript プログラムを実行します。 。

GUI渲染线程

は、ブラウザインターフェースのレンダリングを担当します。インターフェースの再描画(Repaint)が必要な場合、または何らかの操作によってリフロー(Reflow)が発生した場合、このスレッドが実行されます。ただし、GUI レンダリング スレッドと JavaScript エンジンは相互に排他的であることに注意してください。JavaScript エンジンが実行されると、GUI スレッドは一時停止され、GUI の更新はキューに保存され、JavaScript が実行されるとすぐに実行されます。エンジンはアイドル状態です。

事件触发线程

、イベントがトリガーされると、スレッドはそのイベントを保留キューの最後に追加し、JavaScript エンジンによる処理を待ちます。これらのイベントは、setTimeout などの JavaScript エンジンによって現在実行されているコード ブロックから、またはマウス クリックや Ajax 非同期リクエストなどのブラウザ カーネル内の他のスレッドから発生する可能性があります。ただし、JavaScript のシングルスレッド関係により、すべてのイベントが発生します。これらのイベントはキューに入れて、JavaScript エンジンによる処理を待つ必要があります (スレッド内で同期コードが実行されていない場合にのみ、非同期コードが実行されます)。

ここで、元の例を確認してみましょう:

var start = new Date();
 var end = 0;
 setTimeout(function() {  console.log(new Date() - start); }, 500);
 while (new Date() - start <= 1000) {}


setTimeout

の遅延時間は500ミリ秒ですが、

while

ループの存在により、間隔が1000ミリ秒を超える場合にのみ、 while ループから抜け出します。つまり、1000 ミリ秒より前に、while ループが JavaScript スレッドを占有していました。つまり、while から抜け出すのを待った後にのみ、スレッドはアイドル状態になり、以前に定義された setTimeout を実行します。

最後に、

setTimeout

はタスク(実行する必要のある関数)が指定された時間後にタスクキューに挿入されて待機することを保証するだけであり、タスクがいつ実行されるかは保証しないと結論付けることができます。 。 JavaScript を実行しているスレッドが空になったら、タスクをキューから削除して実行します。

JavaScript スレッドは時間のかかる操作によってブロックされないため、キュー内のタスクをすぐに取り出して実行できます。また、このキュー メカニズムが非同期実行の錯覚を生み出します。

2. SetTimeout の良いパートナー "0"

おそらく次のコードを見たことがあるでしょう:

setTimeout(function(){ // statement}, 0);


上記のコードは即時実行を意味します。本来の目的は、呼び出した関数をすぐに実行することですが、実際には、setTimeout には最小実行時間が設定されており、指定された時間がその時間より短い場合、ブラウザーは許容される最小実行時間を使用するためです。つまり、setTimeout の遅延時間を 0 に設定しても、呼び出されたプログラムはすぐには開始されません。

ブラウザごとに実際の状況は異なります。IE8以前の時間精度は15.6msです。ただし、HTML5 の登場により、ブラウザの高度なバージョン (Chrome、IE9+ など) では、定義された最小時間間隔は 4 ミリ秒以上となり、この値よりも低い場合は自動的に増加します。2010 年には。その後、公開されたブラウザ全体で一貫して採用されました。

そのため、

setTimeout(fn,0)

として記述すると、実際にはキュージャンプ操作を実装し、ブラウザに「できるだけ早く」コールバックを実行するよう要求しますが、実際にどれくらい速くできるかはブラウザに完全に依存します。 。

では、

setTimeout(fn, 0)

は何の役に立つのでしょうか?実際、タスクの実行順序を変更できるという利点があります。ブラウザは現在のタスク キュー内のタスクを完了した後、setTimeout キューに蓄積されたタスクを実行するためです。

遅延後に実行するタスクを0sに設定することで、タスクの実行順序を変更したり、タスクの発生を遅らせたり、非同期で実行させることができます。

インターネットでよくある例を見てみましょう:

document.querySelector(&#39;#one input&#39;).onkeydown = function() {  
     document.querySelector(&#39;#one span&#39;).innerHTML = this.value;
 }; 
document.querySelector(&#39;#second input&#39;).onkeydown = function() {    
     setTimeout(function() {  
         document.querySelector(&#39;#second span&#39;).innerHTML = document.querySelector(&#39;#second input&#39;).value; }, 0);
};

`实例:实例

当你往两个表单输入内容时,你会发现未使用setTimeout函数的只会获取到输入前的内容,而使用setTimeout函数的则会获取到输入的内容。

这是为什么呢?

因为当按下按键的时候,JavaScript 引擎需要执行 keydown 的事件处理程序,然后更新文本框的 value 值,这两个任务也需要按顺序来,事件处理程序执行时,更新 value值(是在keypress后)的任务则进入队列等待,所以我们在 keydown 的事件处理程序里是无法得到更新后的value的,而利用 setTimeout(fn, 0),我们把取 value 的操作放入队列,放在更新 value 值以后,这样便可获取出文本框的值。

未使用setTimeout函数,执行顺序是:`onkeydown => onkeypress => onkeyup

使用setTimeout函数,执行顺序是:

onkeydown => onkeypress => function => onkeyup`

虽然我们可以使用

keyup

来替代

keydown

,不过有一些问题,那就是长按时,

keyup

并不会触发。

长按时,keydown、keypress、keyup的调用顺序:

keydown
keypress
keydown
keypress
...
keyup

也就是说keyup只会触发一次,所以你无法用keyup来实时获取值。

我们还可以用

setImmediate()

来替代

setTimeout(fn,0)



if (!window.setImmediate) {  
    window.setImmediate = function(func, args){  
      return window.setTimeout(func, 0, args);  
   };  
  window.clearImmediate = window.clearTimeout;
 }

setImmediate()`方法用来把一些需要长时间运行的操作放在一个回调函数里,在浏览器完成后面的其他语句后,就立刻执行这个回调函数,必选的第一个参数func,表示将要执行的回调函数,它并不需要时间参数。

注意:目前只有IE10支持此方法,当然,在Nodejs中也可以调用此方法。

3、setTimeout的一些秘密

3.1 setTimeout中回调函数的this

由于setTimeout() 方法是浏览器 window 对象提供的,因此第一个参数函数中的this其实是指向window对象,这跟变量的作用域有关。

看个例子:

var a = 1; 
var obj = {  
a: 2, 
 test: function() {  setTimeout(function(){  console.log(this.a);  }, 0);  
} 
}; 
obj.test(); // 1

不过我们可以通过使用bind()方法来改变setTimeout回调函数里的this

var a = 1; 
var obj = { 
 a: 2, 
 test: function() {  
setTimeout(function(){  
console.log(this.a);  
}.bind(this), 0);  
}
 }; 
obj.test(); // 2

3.2 setTimeout不止两个参数

我们都知道,setTimeout的第一个参数是要执行的回调函数,第二个参数是延迟时间(如果省略,会由浏览器自动设置。在IE,FireFox中,第一次配可能给个很大的数字,100ms上下,往后会缩小到最小时间间隔,Safari,chrome,opera则多为10ms上下。)

其实,setTimeout可以传入第三个参数、第四个参数….,它们表示神马呢?其实是用来表示第一个参数(回调函数)传入的参数。

setTimeout(function(a, b){  
console.log(a); // 3 
console.log(b); // 4},0, 3, 4);


 以上就是JavaScript 开发者应该知道的 setTimeout 秘密 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JavaScript in Action:実際の例とプロジェクトJavaScript in Action:実際の例とプロジェクトApr 19, 2025 am 12:13 AM

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

JavaScriptとWeb:コア機能とユースケースJavaScriptとWeb:コア機能とユースケースApr 18, 2025 am 12:19 AM

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

JavaScriptエンジンの理解:実装の詳細JavaScriptエンジンの理解:実装の詳細Apr 17, 2025 am 12:05 AM

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Python vs. JavaScript:学習曲線と使いやすさPython vs. JavaScript:学習曲線と使いやすさApr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

Python vs. JavaScript:コミュニティ、ライブラリ、リソースPython vs. JavaScript:コミュニティ、ライブラリ、リソースApr 15, 2025 am 12:16 AM

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

C/CからJavaScriptへ:すべてがどのように機能するかC/CからJavaScriptへ:すべてがどのように機能するかApr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

JavaScriptエンジン:実装の比較JavaScriptエンジン:実装の比較Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)