ホームページ >ウェブフロントエンド >jsチュートリアル >jsによる動作機構の詳細解析(解析例)

jsによる動作機構の詳細解析(解析例)

不言
不言転載
2018-10-29 14:04:471836ブラウズ

この記事では、js での動作メカニズムの詳細な分析 (分析例) を紹介します。必要な方は参考にしていただければ幸いです。

1. はじめに

この記事では、JavaScript の操作メカニズムについて説明します。この部分は、インタビューの質問から始めましょう。非常に簡単そうに見えますが、JavaScript の実行メカニズムを理解していないと、間違った答えを導き出す可能性があります。質問の答えは 1 2 3 を順番に出力することです。疑問がある場合は、以下に詳しい説明があります。

2. JS のシングル スレッドの概念を理解する

JavaScript 言語の主要な機能の 1 つはシングル スレッドです。つまり、

できることは 1 つだけです。同時に### 。では、なぜ JavaScript は複数のスレッドを持てないのでしょうか?これにより効率が向上します。

JavaScript の単一スレッドは、その目的に関連しています。ブラウザーのスクリプト言語としての JavaScript の主な目的は、ユーザーと対話して DOM を操作することです。これにより、シングルスレッドのみが可能であることが決まります。そうでない場合は、非常に複雑な同期の問題が発生します。たとえば、JavaScript に同時に 2 つのスレッドがあるとします。1 つのスレッドが特定の DOM ノードにコンテンツを追加し、もう 1 つのスレッドがそのノードを削除するとします。この場合、ブラウザーはどちらのスレッドを使用すればよいでしょうか。 したがって、複雑さを避けるために、JavaScript は誕生以来シングルスレッドであり、これがこの言語の中心的な機能となっており、今後も変更されることはありません。
3. タスク キュー (メッセージ キュー) について

シングル スレッドとは、すべてのタスクをキューに入れる必要があり、前のタスクが完了するまで次のタスクは実行されないことを意味します。前のタスクに時間がかかると、次のタスクも待たされることになります。 JavaScript 言語の設計者はこの問題に気づき、すべてのタスクを 2 つのタイプに分類しました。

1 つは同期タスク (synchronous)、もう 1 つは非同期タスク (asynchronous)

です。同期タスクは、メイン スレッドで実行するためにキューに入れられたタスクを指します。次のタスクは、前のタスクが実行された後にのみ実行できます。非同期タスクは、メイン スレッドには入らず、「タスク キュー」にのみ入るタスクを指します。 「タスクキュー」が非同期タスクを実行できることをメインスレッドに通知すると、タスクは実行のためにメインスレッドに入ります。次に、2 つの例を使用して、同期タスクと非同期タスクの違いを説明します。

console.log(1);
setTimeout(function(){
console.log(3);
},0);
console.log(2);
请问数字打印顺序是什么?
答えが A の場合、正解おめでとうございます。これは同期タスクであり、プログラムは上から実行されるためです。 While() は無限ループしますが、次のステートメントは実行できません。
console.log("A");
while(true){ }
console.log("B");
请问最后的输出结果是什么?
答えが A の場合、おめでとうございます。JS の動作メカニズムについて表面的には理解できました。質問内の setTimeout() は非同期タスクです。

すべての同期タスクが実行されるまで、非同期タスクは実行されません。

これについては、以下で詳しく説明します。

4. イベント ループを理解する

非同期実行の実行メカニズムは次のとおりです:

すべての同期タスクがオンになります。メインスレッドの実行。実行コンテキストスタックを形成します。
  1. メインスレッドの他に「タスクキュー」もあります。非同期タスクに実行結果がある限り、イベントは「タスク キュー」に配置されます。
  2. 「実行スタック」内のすべての同期タスクが実行されると、システムは「タスク キュー」を読み取り、その中にどのようなイベントがあるかを確認します。これらの対応する非同期タスクは待機状態を終了し、実行スタックに入り、実行を開始します。
  3. メインスレッドは上記の 3 番目のステップを繰り返し続けます。
  4. メイン スレッドは「タスク キュー」からイベントを読み取ります。このプロセスは周期的であるため、動作メカニズム全体はイベント ループとも呼ばれます。メインスレッドが空である限り、「タスクキュー」を読み取ります。これが JavaScript
の実行メカニズムです。このプロセスは何度も繰り返されます。下の図はこの点をよく示しています。

jsによる動作機構の詳細解析(解析例)5. 非同期タスクキューに入れるステートメントとそのタイミング

一般的には以下の 4 つがあります。非同期タスクキューに入れるステートメントの種類:

setTimeout および setlnterval
  1. DOMevent
  2. ES6 Promise
  3. Ajax 非同期リクエスト
  4. JavaScript コードは 2 段階で実行されます
:

1. 事前解析 --- すべての関数定義、すべての変数宣言を事前に進め、事前に変数を割り当てません。

##2. 実行 --- 上から実行します。 (jsの動作機構による)

非同期タスクキューに入れるタイミングについては、setTimeoutの例とAjaxの例で詳しく説明します。

例题1
for (var i = 0; i <p>for循环一次碰到一个 setTimeout(),<strong>并不是马上把setTimeout()拿到异步队列中,而要等到一秒后,才将其放到任务队列里面</strong>,一旦"执行栈"中的所有同步任务执行完毕(即for循环结束,此时i已经为5),系统就会读取已经存放"任务队列"的setTimeout()(有五个),于是答案是输出5个5。</p><p>上面也提到,<strong>在到达指定时间时,定时器就会将相应回调函数插入“任务队列”尾部。这就是“定时器(timer)”功能</strong>。</p><p><strong>关于定时器的重要补充</strong>:</p><p>定时器包括setTimeout与 setInterval 两个方法。它们的第二个参数是指定其回调函数推迟/每隔多少毫秒数后执行。</p><p>对于第二个参数有以下需要注意的地方:</p><p>当第二个参数缺省时,默认为 0;</p><p>当指定的值小于 4 毫秒,则增加到 4ms(4ms 是 HTML5 标准指定的,对于 2010 年及之前的浏览器则是 10ms);也就是说至少需要4毫秒,该setTimeout()拿到任务队列中。</p><pre class="brush:php;toolbar:false">例题2
$.ajax({
url:“xxxxx",
success:function (result){
console.log("a")
   }
})
setTimeout(function (){
console.log("b")
},100)
setTimeout(function (){
console.log("c")
})
console.log("d");

jsによる動作機構の詳細解析(解析例)

ajax加载完成时才会放入异步队列,至于这段时间不确定,所有有两种情况:①大于100ms,最后的结果是 d c b a ;②小于100ms,最后的结果便是d c a b。

六、题外话

如果要输出0~4,上面例题应该如何修改?

  1. 将var变为let

for (let i = 0; i <p>2.加个立即执行函数</p><pre class="brush:php;toolbar:false">for (var i = 0; i <p>3.也可以通过这样加闭包</p><pre class="brush:php;toolbar:false">for(var i = 1;i 

以上がjsによる動作機構の詳細解析(解析例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。