ホームページ > 記事 > ウェブフロントエンド > 古典的な手法: シングルスレッドと非同期 JavaScript
この記事では、JavaScript のシングルスレッドと非同期に関する関連知識を提供します。お役に立てば幸いです。
この記事を書くにあたり、私もたくさんの記事を読みましたが、ほとんどが非常に単純で、概念的なことは非常に曖昧だったので、いくつかのコースを聞いて探しました将来のレビューのためにここに簡単にまとめておきます~
1. プロセス : プログラムが完成したら実行されると、ユニークメモリ空間を占有します ---- Windows タスク マネージャを通じてプロセスを表示できます;
##2. スレッド: これはプロセス内の 独立した 実行単位であり、プログラム実行の完全なプロセスであり、CPU の基本的なスケジューリング単位です。
3. プロセスとスレッドの関係:
* 通常、プロセス内には少なくとも 1 つの実行中のスレッドがあります:メイン スレッド -- プロセスが終了した後開始 自動的に作成;
* 1 つのプロセスで複数のスレッドを同時に実行することもできます。プログラムはマルチスレッド;
* データプロセス内では、複数のスレッドで直接共有できます。 * 複数のプロセス間でデータを直接共有することはできません4. ブラウザは単一プロセスを実行していますか? * 一部は単一プロセスです * firefox * 一部は複数プロセスです * chrome5.ブラウザはマルチプロセスです どのプロセスが実行されていますか?
* タスク マネージャ==>プロセス6. ブラウザです。シングルスレッドで実行されていますか? マルチスレッドですか?
* これらはすべてマルチスレッドで実行されます//栗子 console.log(1) console.log(2) console.log(3) //输出顺序 1 2 32. JavaScript がシングルスレッドである理由
同期タスク: in メインスレッド上 実行のためにキューに入れられたタスクは、 最初の タスクが完了した後にのみ実行できます。 すべての同期タスクはメインスレッドで実行されます。 実行スタック
(実行コンテキスト スタック) を形成します。非同期タスク:
タスクはメイン スレッドの外側で 実行されます。メイン スレッドの外側には、「タスク キュー」(タスク キュー) もあります。 )、非同期タスクが完了すると、待機するコールバック関数の形式で タスク キュー に入れられます。メイン スレッドがアイドル状態になると、メイン スレッドはイベント キューに移動して待機します。待機中のコールバック関数を取り出してメインスレッドに入れて実行します。この処理を繰り返し実行することで、jsのイベントループ機構(イベントループ)が形成されます。
//栗子 // 同步 console.log(1) // 异步 setTimeout(()=>{ console.log(2) },100) // 同步 console.log(3) //输出顺序 1 3 22. JavaScript が非同期である必要がある理由JS コードの実行中に、特定のコード部分が長時間実行されると、後続のコードは長時間実行されなくなります。その結果、
3. 非同期 JavaScript の実装方法
1) 実行スタックとタスク キュー 実際、JS は最初にいくつかの概念を理解しましょう:
当一个JS文件第一次执行的时候,js引擎会 解析这段代码,并将其中的同步代码 按照执行顺序加入执行栈中,然后从头开始执行。如果当前执行的是一个方法,那么js会向执行栈中添加这个方法的执行环境,然后进入这个执行环境继续执行其中的代码。当这个执行环境中的代码 执行完毕并返回结果后,js会退出这个执行环境并把这个执行环境销毁,回到上一个方法的执行环境。这个过程反复进行,直到执行栈中的代码全部执行完毕。
栗子
//(1) console.log(1) //(2) setTimeout(()=>{ console.log(2) },100) //(3) console.log(3)
所以结果是 1 3 2;
注意:setTimeout/Promise等我们称之为任务源。而进入任务队列的是他们指定的回调;
上面的循环只是一个宏观的表述,实际上异步任务之间也是有不同的,分为 宏任务(macro task) 与 微任务(micro task),最新的标准中,他们被称为 task与 jobs
下面我们再详细讲解一下执行过程:
执行栈在执行的时候,会把宏任务放在一个宏任务的任务队列,把微任务放在一个微任务的任务队列,在当前执行栈为空的时候,主线程会 查看微任务队列是否有事件存在。如果微任务队列不存在,那么会去宏任务队列中 取出一个任务 加入当前执行栈;如果微任务队列存在,则会依次执行微任务队列中的所有任务,直到微任务队列为空(同样,是吧队列中的事件加到执行栈执行),然后去宏任务队列中取出最前面的一个事件加入当前执行栈...如此反复,进入循环。
注意:
栗子
//(1) setTimeout(()=>{ console.log(1) // 宏任务 },100) //(2) setTimeout(()=>{ console.log(2) // 宏任务 },100) //(3) new Promise(function(resolve,reject){ //(4) console.log(3) // 直接打印 resolve(4) }).then(function(val){ //(5) console.log(val); // 微任务 }) //(6) new Promise(function(resolve,reject){ //(7) console.log(5) // 直接打印 resolve(6) }).then(function(val){ //(8) console.log(val); // 微任务 }) //(9) console.log(7) // 直接打印 //(10) setTimeout(()=>{ console.log(8) // 宏任务,单比(1)(2)宏任务早 },50)
上面的代码在node和chrome环境的正确打印顺序是 3 5 7 4 6 8 1 2
下面分析一下执行过程:
注: レンダリングもマクロ タスクであるため、レンダリングを実行する必要があります。したがって、実行スタック内の同じスタイルを同時に同期的に変更するコードが複数ある場合は、最後のコードのみをレンダリングします。
関連する推奨事項: JavaScript 学習チュートリアル
以上が古典的な手法: シングルスレッドと非同期 JavaScriptの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。