Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JavaScriptはなぜシングルスレッドでも非同期処理ができるのか/Why Can JavaSctipt Invoke Asynchronous in Single Thread?

195f71c8183f8d27da66aa0618f293b6?s=47 task4233
September 07, 2021

JavaScriptはなぜシングルスレッドでも非同期処理ができるのか/Why Can JavaSctipt Invoke Asynchronous in Single Thread?

JavaScriptはシングルスレッドであることが知られています。そして、Promiseを用いた非同期処理ができることは周知の事実です。では、なぜシングルスレッドで非同期処理ができるのでしょうか?
その点について、非同期処理のための2種類のQueuesについて触れつつ、コードベースでの説明も行います。

195f71c8183f8d27da66aa0618f293b6?s=128

task4233

September 07, 2021
Tweet

Transcript

  1. JavaScriptは なぜシングルスレッドでも 非同期処理ができるのか お昼のLT 2021/09/07 Takashi Mima(@task4233)

  2. 本LTの目標 ・JavaScript(ECMAScript)がシングルスレッドで非同期処理を  実現している方法をざっくり理解すること 本LTの想定対象者 ・JavaScriptの基本的な文法を理解している人 ・シングルスレッドの概念を理解している人 本LTの非想定対象者 ・内部実装にあまり興味がない人 ・JavaScriptを全く触れたことがない人 2

  3. TL;DR(ECMAScript) JavaScriptはシングルスレッド ・Event LoopとCall Stackを用いて動いている 非同期処理を実現するための2種類のQueue ・Micro Task Queue ・Macro

    Task Queue 処理の優先度 ・Call Stack > Micro Task Queue > Macro Task Queue 3
  4. 自己紹介 ・Takashi Mima(@task4233) ・芝浦工業大学 M1 ・サーバサイドとセキュリティ ・散歩とGoが好き 4

  5. JavaScript(以下JS)の変遷 1995 LiveScriptの誕生(後のJS) 1995 JScriptの登場(当時のJSと互換性ナシ) 1997 ECMAに標準化を依頼(いわゆるECMAScript) 2000~ 第3版派と第4版派の軋轢(低迷) 2005~ Ajax, prototype.js, jQuery等の登場(持ち直し)

    2008 V8エンジンの登場(JITコンパイルによる高速化) 2009 Node.jsの登場(モジュール管理が可能に) …… 5
  6. 非同期処理に欠かせないPromiseオブジェクト State(状態)とValue(値)を持つ ・Stateはfulfilled✅ /rejected❌ /pending⏳ の3種類 ・Valueは結果 Promise(resolve func, reject

    func)で生成 ・fulfilled✅ => resolve funcを実行 ・rejected❌ => reject funcを実行 状態を持てるので、非同期処理に用いられる 6
  7. JavaScriptはシングルスレッド シングルスレッド ・1度に1つのタスクしか実行できない ・メモリ空間での競合が起きない Event Loopに従ってタスクを処理する ・タスクを処理する無限ループ ・DOMの更新もタスクの1つ 処理はCall Stackで実行される

    ・処理のためのStack ・処理を実行するWEB APIにデータを流す ・Pushed -> Invoke -> Pop(& return Value)の順に 7
  8. シングルスレッド? 8

  9. あるタスクの実行中には 非同期処理を動かせないはず (シングルスレッドなので) 9

  10. Q. どうやって非同期処理してるの? 🤔 10

  11. A. Queueを別に持つことで 非同期っぽく逐次処理している 11

  12. 2種類のQueues Micro Task Queue ・優先度の高い方のQueue ・process.nextTick, Promise callbackなど Macro Task

    Queue ・優先度が低い方のQueue ・setTimeout, setInterval, setImmediateなど 処理の優先度 ・Call Stack > Micro Task Queue > Macro Task Queue 非同期処理に 用いられる 12
  13. コードベースで考えてみる Call Stack Micro Task Queue Macro Task Queue Event

    Loop Log: 13
  14. Log: コードベースで考えてみる Call Stack Micro Task Queue Macro Task Queue

    Event Loop 14
  15. Log: コードベースで考えてみる console.log(‘Start’); Micro Task Queue Macro Task Queue Event

    Loop 15
  16. コードベースで考えてみる Call Stack Micro Task Queue Macro Task Queue Event

    Loop Log: Start 16
  17. コードベースで考えてみる Call Stack Micro Task Queue () => { console.log(‘timeout’)

    } Event Loop Log: Start 17
  18. コードベースで考えてみる Call Stack Micro Task Queue () => { console.log(‘timeout’)

    } Event Loop Log: Start 18
  19. コードベースで考えてみる Call Stack (res) => { console.log(res); } () =>

    { console.log(‘timeout’) } Event Loop Log: Start 19
  20. コードベースで考えてみる Call Stack (res) => { console.log(res); } () =>

    { console.log(‘timeout’) } Event Loop Log: Start 20
  21. コードベースで考えてみる console.log(‘End’); (res) => { console.log(res); } () => {

    console.log(‘timeout’) } Event Loop Log: Start 21
  22. コードベースで考えてみる Call Stack (res) => { console.log(res); } () =>

    { console.log(‘timeout’) } Event Loop Log: Start    End 22
  23. コードベースで考えてみる Call Stack (res) => { console.log(res); } () =>

    { console.log(‘timeout’) } Event Loop Log: Start    End 23
  24. コードベースで考えてみる (res) => { console.log(res); } Micro Task Queue ()

    => { console.log(‘timeout’) } Event Loop Log: Start    End 24
  25. コードベースで考えてみる Call Stack Micro Task Queue () => { console.log(‘timeout’)

    } Event Loop Log: Start    End    promise 25
  26. コードベースで考えてみる () => { console.log(‘timeout’) } Micro Task Queue Macro

    Task Queue Event Loop Log: Start    End    promise 26
  27. コードベースで考えてみる Call Stack Micro Task Queue Macro Task Queue Event

    Loop Log: Start    End    promise    timeout 27
  28. まとめ JavaScriptはシングルスレッド ・Event LoopとCall Stackを用いて動いている 非同期処理を実現するための2種類のQueue ・Micro Task Queue ・Macro

    Task Queue 処理の優先度 ・Call Stack > Micro Task Queue > Macro Task Queue ありがとうございました! 28
  29. 参考資料 ・✨♻ JavaScript Visualized: Event Loop - DEV Community ・⭐🎀

    JavaScript Visualized: Promises & Async/Await - DEV Community ・Understanding the node.js event loop ・voyagegroup/treasure-javascript-2020: Treasure Frontend 講義資料とか ・ そうだったのか! よくわかる process.nextTick() node.jsのイベントループを 理解する 29