目次
setTimeout(0)函数的作用
setTimeout 和 setInterval 在执行异步代码的时候有着根本的不同
ホームページ ウェブフロントエンド jsチュートリアル JavaScript シングルスレッドメカニズムと setTimeout 実行原理の概要 (コード付き)

JavaScript シングルスレッドメカニズムと setTimeout 実行原理の概要 (コード付き)

Mar 27, 2019 am 09:09 AM
javascript

この記事では、JavaScript のシングル スレッド メカニズムと setTimeout の実行原理 (コード付き) を紹介します。これには一定の参考値があります。必要な友人は参照できます。お役に立てれば幸いです。

JavaScript エンジンのシングルスレッド メカニズム

まず、JavaScript エンジンがシングルスレッド メカニズムであることは明らかです。

JavaScript は単一のスレッドで実行され、複数のコードを同時に実行することはできません。特定のコードが実行されているとき、後続のすべてのタスクは待機する必要があり、タスク キューを形成します。現在のタスクが実行されると、次のタスクがキューから取り出されます。これは、多くの場合「実行のブロック」と呼ばれます。

これは次のように理解できます: JS スレッドで実行する同期コードがない場合にのみ非同期コードが実行されます

つまり、マウスをクリックするか、タイマーが時点に達するか、または Ajaxリクエストが完了する コールバック関数がトリガーされると、これらのイベント ハンドラーまたはコールバック関数はすぐには実行されませんが、すぐにキューに入れられ、スレッドが解放されると実行されます。現在の JavaScript スレッドが時間のかかるコードを実行しているときにマウス クリックが発生した場合、イベント ハンドラーはブロックされ、ユーザーはフィードバックをすぐに確認できなくなります。イベント ハンドラーは、前のタスク キューに入れられるまでタスク キューに入れられます。コードが終了するまで実行は開始されません。コードに setTimeout が設定されている場合、ブラウザは適切な時間にコードをタスク キューに挿入します。この時間を 0 に設定すると、コードはすぐにキューに挿入されますが、実行されません。前のコードが実行されるまで待つ必要があります。したがって、setTimeout は実行時間を保証するものではなく、実行が間に合うかどうかは JavaScript スレッドが混雑しているかアイドル状態であるかによって決まります。

ブラウザのマルチスレッド機構とイベントループ

まず、ブラウザのカーネルがマルチスレッドであることは明らかであり、カーネルの制御下で相互に連携して同期を維持しています。少なくとも 3 つの常駐スレッドを実装する必要があります:

JavaScript エンジン スレッド

GUI レンダリング スレッド

ブラウザ イベント トリガー スレッド

JavaScript エンジンは単一です。 threaded 実行中、ブラウザでは常に JavaScript プログラムを実行するスレッドが 1 つだけです

JavaScript エンジンはイベント駆動型のシングルスレッド実行に基づいています。JS エンジンはタスク キュー内のタスクの到着を待機しています。を追加し、Processing を追加すると、ブラウザーでは常に 1 つの JS スレッドのみが JS プログラムを実行します。

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

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

イベント ループ (イベント ループ): 非同期コードを管理するために使用され、非同期コードはスレッド プールに入れられます。

JavaScript における setTimeout の実装原理

まず、setTimeout 関数が非同期コードであることは明らかですが、実際には setTimeout は真の非同期操作ではありません

原因は次のとおりです。 JS スレッドの動作メカニズム: 非同期コードは、スレッド内で同期コードが実行されていない場合にのみ実行されます。setTimeout は非同期コードであるため、setTimeout は js がアイドル状態のときにのみ実行できます。

前述したように、コード setTimeout に a が設定されている場合、ブラウザは適切な時間にコードをタスク キューに挿入します。この時間が 0 に設定されている場合、コードはすぐにキューに挿入されますが、挿入されません。すぐに実行されますが、前のコードが実行されるまで待つ必要があります。したがって、setTimeout は実行時間を保証するものではなく、実行が間に合うかどうかは JavaScript スレッドが混雑しているかアイドル状態であるかによって決まります。

つまり、setTimeout は、タスク (実行する必要のある関数) が指定された時間後にキューに挿入されて待機することを保証するだけであり、タスクがいつ実行されるかは保証しません。 JavaScript を実行するスレッドは、キューからタスクを取り出し、アイドル状態になったときにそれを実行します。 JavaScript はこのキュー メカニズムを使用して、非同期実行のように見せかけます。

setTimeout のコードがすぐに実行されることがありますが、このコードは非同期で実行されているように感じられます。これは、JavaScript スレッドが時間のかかる操作によってブロックされないため、すぐに削除できるためです。その後、キュー内のタスクが実行されます。

例の分析

上記の理論的根拠を持った後、次の例を分析します。

======= ==== ================================

var t = true;
    
window.setTimeout(function (){
    t = false;
},1000);
    
while (t){}
    
alert('end');
ログイン後にコピー
実行結果: プログラムは無限ループに陥ります。

t = false は実行されないため、alert('end') は実行されません。 ### 分析: ###<p>JS是单线程的,所以会先执行 while(t){} 再 alert,但这个循环体是死循环,所以永远不会执行alert。<br></p> <p>为什么不执行 setTimeout?是因为JS的工作机制是:当线程中没有执行任何同步代码的前提下才会执行异步代码,setTimeout是异步代码,所以 setTimeout 只能等JS空闲才会执行,但死循环是永远不会空闲的,所以 setTimeout 也永远得不到执行。</p> <p>===========================================</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">var start = new Date();      setTimeout(function(){       var end = new Date();       console.log(&quot;Time elapsed: &quot;, end - start, &quot;ms&quot;);   }, 500);          while (new Date - start &lt;= 1000){}</pre><div class="contentsignin">ログイン後にコピー</div></div><p>运行结果:"Time elapsed: 1035 ms" (这里的1035不准确 但是一定是大于1000的)<br/> 解析:</p><p>JS是单线程 setTimeout 异步代码 其回调函数执行必须需等待主线程运行完毕</p><p>当while循环因为时间差超过 1000ms 跳出循环后,setTimeout 函数中的回调才得以执行</p><p>===========================================</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">for(var i=0;i&lt;10;i++){ setTimeout(function() { console.log(i); }, 0); }</pre><div class="contentsignin">ログイン後にコピー</div></div><p>运行结果:输出10个10<br/> 解析:JS单线程 setTimeout 异步代码 任务队列<br/> 问:如何修改可以使上述代码输出 0123456789<br/> 自执行函数 或 使用ES6中的let关键字</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">// 自执行函数 形成闭包 记忆其被创建时的环境 for(var i=0;i&lt;10;i++){ setTimeout((function() { console.log(i); })(), 0); }</pre><div class="contentsignin">ログイン後にコピー</div></div><h3 id="setTimeout-函数的作用">setTimeout(0)函数的作用</h3><p>现在我们了解了setTimeout函数执行的原理,那么它有什么作用呢?<br/>setTimeout函数增加了Javascript函数调用的灵活性,为函数执行顺序的调度提供极大便利。<br/><strong>简言之,改变顺序,这正是setTimeout(0)的作用。</strong></p><p>使用场景示例:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">&lt;input type=&quot;text&quot; onkeydown=&quot;show(this.value)&quot;&gt;   &lt;p&gt;&lt;/p&gt;   &lt;script type=&quot;text/javascript&quot;&gt;     function show(val) {       document.getElementsByTagName('p')[0].innerHTML = val;     }   &lt;/script&gt;</pre><div class="contentsignin">ログイン後にコピー</div></div> <p>这里绑定了 keydown 事件,意图是当用户在文本框里输入字符时,将输入的内容实时地在 <p> 中显示出来。但是实际效果并非如此,可以发现,每按下一个字符时,<p> 中只能显示出之前的内容,无法得到当前的字符。</p> <p>修改代码:</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">  &lt;input type=&quot;text&quot; onkeydown=&quot;var self=this; setTimeout(function(){show(self.value)}, 0)&quot;&gt;     &lt;p&gt;&lt;/p&gt;     &lt;script type=&quot;text/javascript&quot;&gt;       function show(val) {         document.getElementsByTagName('p')[0].innerHTML = val;       }     &lt;/script&gt;</pre><div class="contentsignin">ログイン後にコピー</div></div> <p>这段代码使用setTimeout(0)就可以实现需要的效果了。</p> <p>这里其实涉及2个任务,1个是将键盘输入的字符回写到输入框中,一个是获取文本框的值将其写入p中。第一个是浏览器自身的默认行为,一个是我们自己编写的代码。很显然,必须要先让浏览器将字符回写到文本框,然后我们才能获取其内容写到p中。改变顺序,这正是setTimeout(0)的作用。</p> <p>其他应用场景:有时候,加载一些广告的时候,我们用setTimeout实现异步,好让广告不会阻塞我们页面的渲染。</p> <h3 id="setTimeout-和-setInterval-在执行异步代码的时候有着根本的不同">setTimeout 和 setInterval 在执行异步代码的时候有着根本的不同</h3> <p>如果一个计时器被阻塞而不能立即执行,它将延迟执行直到下一次可能执行的时间点才被执行(比期望的时间间隔要长些)</p> <p>如果setInterval回调函数的执行时间将足够长(比指定的时间间隔长),它们将连续执行并且彼此之间没有时间间隔。</p> <p>本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注PHP中文网的<a href="http://www.php.cn/course/list/17.html" target="_blank">JavaScript视频教程</a>栏目!</p> <p></p>

以上がJavaScript シングルスレッドメカニズムと setTimeout 実行原理の概要 (コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホット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ヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 Dec 17, 2023 pm 02:54 PM

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 Dec 17, 2023 pm 12:09 PM

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 Dec 17, 2023 am 09:39 AM

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

JavaScriptでinsertBeforeを使用する方法 JavaScriptでinsertBeforeを使用する方法 Nov 24, 2023 am 11:56 AM

使用法: JavaScript では、insertBefore() メソッドを使用して、DOM ツリーに新しいノードを挿入します。このメソッドには、挿入される新しいノードと参照ノード (つまり、新しいノードが挿入されるノード) の 2 つのパラメータが必要です。

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

JavaScript と WebSocket: 効率的なリアルタイム画像処理システムの構築 JavaScript と WebSocket: 効率的なリアルタイム画像処理システムの構築 Dec 17, 2023 am 08:41 AM

JavaScript は Web 開発で広く使用されているプログラミング言語であり、WebSocket はリアルタイム通信に使用されるネットワーク プロトコルです。 2 つの強力な機能を組み合わせることで、効率的なリアルタイム画像処理システムを構築できます。この記事では、JavaScript と WebSocket を使用してこのシステムを実装する方法と、具体的なコード例を紹介します。まず、リアルタイム画像処理システムの要件と目標を明確にする必要があります。リアルタイムの画像データを収集できるカメラ デバイスがあるとします。

See all articles