Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
シングルな Javascript の非同期処理
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Jeongmin LEE
June 27, 2024
Programming
200
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
シングルな Javascript の非同期処理
Jeongmin LEE
June 27, 2024
More Decks by Jeongmin LEE
See All by Jeongmin LEE
Redux と状態管理
gardensky511
0
23
TypeScript のコンパイル
gardensky511
0
66
【2025年新卒研修】 React・Next.js は何であるのか
gardensky511
0
140
Webレンダリング最適化の道
gardensky511
0
57
Webレンダリング技術の進化と課題
gardensky511
0
100
Promise と async/await
gardensky511
0
64
集合で理解する Typescript
gardensky511
1
340
Javascript のデータ型 プリミティブ型・オブジェクト
gardensky511
0
180
Other Decks in Programming
See All in Programming
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
320
霧の中の代数的エフェクト
funnyycat
1
390
エンジニアにデザインハーネスを 〜デザインプロセスを規定するためのハーネス〜 / Design harness from an engineer's perspective
rkaga
2
1.5k
PHPだって関数型したい 〜できること、できないこと〜 / fp-in-php
jsoizo
0
210
Claude Team Plan導入・ガイド
tk3fftk
0
200
フィードバックで育てるAI開発
kotaminato
1
120
AIキャラアプリkaiwaの低遅延音声通話基盤をどう作ったか - AWS Gravitonで支える低遅延・低コストAI Agent基盤
mogamit
0
170
Apache Hive: そしてCloud Native Lakehouseへ
okumin
1
130
Claude Opus 4.6以後の受託開発エンジニアの変化(Claude Code開発ノウハウ大公開スペシャルbyクラスメソッド)
iidatakuma
1
770
吝嗇家のためのAI活用 / AI development for miser - ChatGPT + Issue Driven Development
tooppoo
0
190
任せる範囲はこう広がった / How the Scope of AI Delegation Has Expanded
nrslib
1
260
Haskell/Servantを通してWebミドルウェアを捉え直す
pizzacat83
1
580
Featured
See All Featured
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.4k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
A Tale of Four Properties
chriscoyier
163
24k
Side Projects
sachag
455
43k
Are puppies a ranking factor?
jonoalderson
1
3.7k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
220
We Have a Design System, Now What?
morganepeng
55
8.2k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
New Earth Scene 8
popppiees
3
2.4k
AI: The stuff that nobody shows you
jnunemaker
PRO
8
830
Transcript
シングルな Javascript の非同期処理 Javascript 非同期処理完全理解(1)
職業 フロントエンドエンジニア(2020/11 ~) React、Typescript メインでやってます 自己紹介 韓国人です。大学時代にはげしくアニメ オタクをやってて日本語が上手くなりま した。
CONTENTS 1. 同期処理・非同期処理とは 2. Javascript はシングルスレッド 3. Javascript の非同期処理 4.
まとめ
1. 同期処理・非同期処理とは
同期処理 進行中のタスクが終わるまで次のタスクたちは待つ
// 一定時間が経ってから func を実行する function sleep(func, delay) { const delayUntil
= Date.now() + delay; while (Date.now() < delayUntil); func() } function foo() { console.log("foo") } function bar() { console.log("bar") } sleep(foo, 3000) // 3秒経ってから foo を実行する bar() 同期処理
sleep foo bar 同期処理 Blocking (作業中断) delay Time メリット:タスクを順番に処理するので、実行順序が保証される デメリット:前のタスクが終了するまで以降のタスクたちは待ってるので、ブロッキングされる
非同期処理 進行中のタスクが終了されてない状態でも次のタスクを実行
function foo() { console.log("foo") } function bar() { console.log("bar") }
// setTimeout は一定時間が経ってからコールバック関数 foo を実行する setTimeout(foo, 3000) bar() 非同期処理
非同期処理 メリット:現在実行中のタスクが終了してなくても、次のタスクを実行するのでブロッキングが発生しない デメリット:タスクの実行順序が保証されない setTimeout foo bar Non-Blocking Time delay
2. Javascript はシングルスレッド
Javascript はどこで実行されますか? - Web Browser - Node.js - Deno -
Bun 、、などなど(他にもたくさんある) Image From wikipedia
- Web Browser - Node.js - Deno - Bun 今回メインで話す
Javascript はどこで実行されますか? 、、などなど(他にもたくさんある) Image From wikipedia
- Web Browser - Node.js - Deno - Bun Javascript
が実行される環境はすべて Javscript Engine を持ってる Javascript はどこで実行されますか? 、、などなど(他にもたくさんある) Image From wikipedia
- Web Browser - Node.js - Deno - Bun Javascript
が実行される環境はすべて Javscript Engine を持ってる Javascript はどこで実行されますか? 、、などなど(他にもたくさんある) JavaScriptのコードを実行する コンピュータプログラム Image From wikipedia
Javascript Engine の内部 Memory Heap Call Stack
変数とかデータとかを メモリに保存する Memory Heap Call Stack Javascript Engine の内部
初回勉強会で散々話した メモリアサインがここで起こる speakerdeck.com/gardensky511 Memory Heap Call Stack Javascript Engine の内部
関数コールを管理する Memory Heap Call Stack Javascript Engine の内部
Memory Heap Call Stack console.log(i) (1) Javascript コード実行! なんとなくこんなイメージ
Memory Heap Call Stack (3) i 発見 console.log(i) (2) i
ってなんだ、heap から探そう i = "あああああ" なんとなくこんなイメージ *実際にこの形で保存される わけではありません
Memory Heap Call Stack i = "あああああ" (4) 実行!されたら Call
Stack から消える なんとなくこんなイメージ *実際にこの形で保存される わけではありません
出入り口が片方しかないパイプみたいな形のデータ構造(FILO: First In Last Out) Image From wikipedia https://www.geeksforgeeks.org/stack-meaning-in-dsa/ 補足1)Stack
はデータ構造のひとつ
補足2)関数も後でコールされたものが先に実行される Call Stack function multiply(a, b) { return a *
b } function square(n) { return multiply(n, n) } function printSquare(n) { const square = square(n) console.log(square) } printSquare(4)
補足2)関数も後でコールされたものが先に実行される Call Stack function multiply(a, b) { return a *
b } function square(n) { return multiply(n, n) } function printSquare(n) { const square = square(n) console.log(square) } printSquare(4) printSquare(4) square(n) multiply(n, n) ②コール ①コール ③コール ①コール ②コール ③コール
補足2)関数も後でコールされたものが先に実行される Call Stack function multiply(a, b) { return a *
b } function square(n) { return multiply(n, n) } function printSquare(n) { const square = square(n) console.log(square) } printSquare(4) printSquare(4) square(n) multiply(n, n) ③実行 ②実行 ①実行 ②実行 ③実行 ①実行
(大事)Javascript Engine はひとつの Call Stack を持つ Memory Heap Call Stack
= シングルスレッド = Call Stack がひとつ = 一度に一つの関数コールしか処理できない
Memory Heap Call Stack え、、? Call Stack ひとつなら そもそも非同期処理できなくね??? 🤔
= シングルスレッド = Call Stack がひとつ = 一度に一つの関数コールしか処理できない (大事)Javascript Engine はひとつの Call Stack を持つ
3. Javascript の非同期処理
console.log(1+1) setTimeout(function () { console.log(2+2) }, 2000) console.log(3+3) Memory Heap
Call Stack まずは非同期処理を実行してみよう
Memory Heap Call Stack console.log(1+1) まずは非同期処理を実行してみよう ①実行 ①実行 (されて CallStack
から消える) console.log(1+1) setTimeout(function () { console.log(2+2) }, 2000) console.log(3+3)
console.log(1+1) setTimeout(function () { console.log(2+2) }, 2000) console.log(3+3) Memory Heap
Call Stack setTimeout(function () { console.log(2+2) }, 2000) まずは非同期処理を実行してみよう ②実行 ②実行
console.log(1+1) setTimeout(function () { console.log(2+2) }, 2000) console.log(3+3) Memory Heap
Call Stack setTimeout(function () { console.log(2+2) }, 2000) まずは非同期処理を実行してみよう ②実行 ②実行 Call Stack ひとつしかないし、 setTimeout で2待つから次の console.log(3+3) は setTimeout が 終わるまで実行されないのでは、、? 🤔
Memory Heap Call Stack まずは非同期処理を実行してみよう 結論:そんなことない console.log(1+1) 実行 console.log(3+3) 実行
2秒後 console.log(2+2) 実行 console.log(1+1) setTimeout(function () { console.log(2+2) }, 2000) console.log(3+3)
説明しよう! その理由は Javascript Engine とブラウザが協業して非同期処理をしているからだ! (正確には実行環境)
Memory Heap Call Stack Web APIs Task Queue Event Loop
ブラウザの中はざっくりこんな感じ
Memory Heap Call Stack Web APIs Task Queue Event Loop
非同期処理はざっくりこんな感じ console.log(1+1) (されて CallStack から消える) ①実行 console.log(1+1) setTimeout(function () { console.log(2+2) }, 2000) console.log(3+3) ①実行
Memory Heap Web APIs Event Loop setTimeout(function () { console.log(2+2)
}, 2000) ②実行 非同期処理は大体こんな感じ Call Stack console.log(1+1) setTimeout(function () { console.log(2+2) }, 2000) console.log(3+3) ②実行 Task Queue
Memory Heap Web APIs Event Loop 非同期処理は大体こんな感じ setTimeout(function () {
console.log(2+2) }, 2000) こっちに移動する (Call Stack じゃなくてここで2秒待つ) Call Stack setTimeout(function () { console.log(2+2) }, 2000) console.log(1+1) setTimeout(function () { console.log(2+2) }, 2000) console.log(3+3) ②実行 Task Queue
Memory Heap Web APIs Event Loop setTimeout が実行されたとみなされ、 Call Stack
からは消える 非同期処理は大体こんな感じ setTimeout(function () { console.log(2+2) }, 2000) Call Stack console.log(1+1) setTimeout(function () { console.log(2+2) }, 2000) console.log(3+3) ②実行 Task Queue
Memory Heap Web APIs Event Loop 非同期処理は大体こんな感じ console.log(3+3) ③実行 (されて
CallStack から消える) setTimeout(function () { console.log(2+2) }, 2000) Call Stack console.log(1+1) setTimeout(function () { console.log(2+2) }, 2000) console.log(3+3) ③実行 Task Queue
Memory Heap Web APIs Event Loop 非同期処理は大体こんな感じ setTimeout(function () {
console.log(2+2) }, 2000) 2秒待ち終わったら、、 Call Stack console.log(1+1) setTimeout(function () { console.log(2+2) }, 2000) console.log(3+3) Task Queue
Memory Heap Web APIs Event Loop 非同期処理は大体こんな感じ function () {
console.log(2+2) } コールバック関数を Task Queue に送る Call Stack console.log(1+1) setTimeout(function () { console.log(2+2) }, 2000) console.log(3+3) Task Queue
Memory Heap Web APIs Event Loop 非同期処理は大体こんな感じ function () {
console.log(2+2) } Call Stack が空だったら、 Queueでまってるコールバック関数を Call Stack に移動させ、実行 Call Stack console.log(1+1) setTimeout(function () { console.log(2+2) }, 2000) console.log(3+3) ④実行 Task Queue
Memory Heap Web APIs Event Loop 非同期処理は大体こんな感じ console.log(1+1) setTimeout(function ()
{ console.log(2+2) }, 2000) console.log(3+3) Call Stack という流れでこうなる Task Queue
ひとつずつ理解してみよう
何が Web APIs に送られる? - タイマー処理(setTimeout、setInterval など) - HTTPリクエスト(XMLHttpRequest, fetch
など) - イベントハンドラー 、、などなど Memory Heap Call Stack Web APIs Task Queue Event Loop
何が Web APIs に送られる? Memory Heap Call Stack Web APIs
Event Loop 特定条件を満されるまで待ってから コールバック関数実行させたい 処理が Web APIs に行くイメージ - タイマー処理(setTimeout、setInterval など) - HTTPリクエスト(XMLHttpRequest, fetch など) - イベントハンドラー 、、などなど Task Queue
Task Queue とは - Event Queue、Callback Queue ともいうらしい - 非同期処理後に実行されるコールバック関数たちの待合室
Memory Heap Call Stack Web APIs Task Queue Event Loop
Task Queue とは Memory Heap Call Stack Web APIs Event
Loop 特定条件を満されたらコールバックが Queueに移動、実行されるのを待つ 特定条件を満されるまで待ってから コールバック関数実行させたい 処理が Web APIs に行くイメージ Task Queue - Event Queue、Callback Queue ともいうらしい - 非同期処理後に実行されるコールバック関数たちの待合室
補足)Queue もデータ構造のひとつ Image From wikipedia https://www.geeksforgeeks.org/what-is-queue-data-structure/ 出入り口が両方あるパイプみたいな形のデータ構造(FIFO: First In First
Out)
Memory Heap Call Stack Web APIs Task Queue Event Loop
なんとなくこんな感じ button.addEventListener('click', function() { console.log('clicked'); }) setTimeout(function () { console.log(10) }, 2000) button.addEventListener(' click', function() { console.log('clicked'); }) ①実行 ①実行
Memory Heap Call Stack Web APIs Event Loop button.addEventListener('click', function()
{ console.log('clicked'); }) setTimeout(function () { console.log(10) }, 2000) button.addEventListener(' click', function() { console.log('clicked'); }) ①実行 こっちに移動する なんとなくこんな感じ Task Queue
Memory Heap Call Stack Web APIs Event Loop button.addEventListener('click', function()
{ console.log('clicked'); }) setTimeout(function () { console.log(10) }, 2000) button.addEventListener(' click', function() { console.log('clicked'); }) ②実行 setTimeout(function () { console.log(10) }, 2000) ②実行 なんとなくこんな感じ Task Queue
Memory Heap Call Stack Web APIs Event Loop button.addEventListener('click', function()
{ console.log('clicked'); }) setTimeout(function () { console.log(10) }, 2000) button.addEventListener(' click', function() { console.log('clicked'); }) setTimeout(function () { console.log(10) }, 2000) こっちに移動する なんとなくこんな感じ Task Queue
Memory Heap Call Stack Web APIs Event Loop button.addEventListener('click', function()
{ console.log('clicked'); }) setTimeout(function () { console.log(10) }, 2000) button.addEventListener(' click', function() { console.log('clicked'); }) setTimeout(function () { console.log(10) }, 2000) 2秒経った時に button クリックもした! なんとなくこんな感じ Task Queue
Memory Heap Call Stack Web APIs Event Loop button.addEventListener('click', function()
{ console.log('clicked'); }) setTimeout(function () { console.log(10) }, 2000) button.addEventListener(' click', function() { console.log('clicked'); }) function () { console.log(10) } function() { console.log('clicked'); } 順番にQueueに入る なんとなくこんな感じ 2秒経った時に button クリックもした! Task Queue
Memory Heap Call Stack Web APIs Event Loop button.addEventListener('click', function()
{ console.log('clicked'); }) setTimeout(function () { console.log(10) }, 2000) button.addEventListener(' click', function() { console.log('clicked'); }) function () { console.log(10) } function() { console.log('clicked'); } Call Stack が空だったら、Queueで 待ってるコールバック関数たちを送る なんとなくこんな感じ Task Queue
Memory Heap Call Stack Web APIs Task Queue Event Loop
(大事) Call Stack が空なときだけ Queue でまってる子たちが Call Stack に行ける button.addEventListener(' click', function() { console.log('clicked'); }) function () { // なんかずっとやってる } function() { console.log('clicked'); } もし Call Stack が空じゃなかったら、 Queue のタスクは Call Stack に来れない Call Stackに行けない、、
Memory Heap Call Stack Web APIs Event Loop だからブラウザで重い処理をしてはいけないのだ 10秒ぐらいかかる
めちゃ重い計算処理 まってる処理1 こいつがおわるまでなにもできない 例)ボタンクリックしてもなにも起きない まってる処理2 まってる処理3 まってる処理4 Call Stackに行けない、、 Webサイトが明らかに遅いとか、 なんかクリックしても時差で実行 されるのは Call Stack が詰まってる ということでしょう、、 Task Queue
Event Loop とは - Call Stack と Queue をモニタリングしてる -
Call Stack が空いてて、 Queue で待ってるタスクがある場合 Call Stack にタスクを移動させる Memory Heap Call Stack Web APIs Event Loop Task Queue
ちょっとだけ応用してみましょう
console.log(1) setTimeout(function () { console.log(2) }, 0) console.log(3) Memory Heap
Call Stack Web APIs Task Queue Event Loop setTimeout で 0 秒を待たせてみた 0 秒待つ = 待たないだから、 1、2、3 順に出力されそうな?感じ?
Memory Heap Call Stack Web APIs Event Loop setTimeout で
0 秒を待たせてみた 結論:そんなことない console.log(1) setTimeout(function () { console.log(2) }, 0) console.log(3) Task Queue
console.log(1) setTimeout(function () { console.log(2) }, 0) console.log(3) Memory Heap
Call Stack Web APIs Event Loop なんでそうなるのか ①実行 (されて CallStack から消える) console.log(1) ①実行 Task Queue
console.log(1) setTimeout(function () { console.log(2) }, 0) console.log(3) Memory Heap
Call Stack Web APIs Event Loop なんでそうなるのか setTimeout(function () { console.log(2) }, 0) Call Stackに入る ②実行 Task Queue
Memory Heap Call Stack Web APIs Event Loop setTimeout(function ()
{ console.log(2) }, 0) こっちに移動する (待ち時間が0秒だろうが 1時間だろうが関係ない) console.log(1) setTimeout(function () { console.log(2) }, 0) console.log(3) ②実行 なんでそうなるのか Task Queue
Memory Heap Call Stack Web APIs Event Loop setTimeout で
0 秒を待たせてみた function() { console.log(2) } 0秒後 Queue に入る console.log(1) setTimeout(function () { console.log(2) }, 0) console.log(3) ②実行 Task Queue
Memory Heap Call Stack Web APIs Event Loop setTimeout で
0 秒を待たせてみた console.log(3) function() { console.log(2) } Call Stack は次の同期処理をやる console.log(1) setTimeout(function () { console.log(2) }, 0) console.log(3) ③実行 Call Stack が空に なるのを待つ Task Queue
Memory Heap Call Stack Web APIs Event Loop setTimeout で
0 秒を待たせてみた function() { console.log(2) } Call Stack が空いたらコールバック関数が Call stack に入り、実行される console.log(1) setTimeout(function () { console.log(2) }, 0) console.log(3) ④実行 Task Queue
Memory Heap Call Stack Web APIs Event Loop setTimeout で
0 秒を待たせてみた console.log(1) setTimeout(function () { console.log(2) }, 0) console.log(3) Task Queue という流れでこうなる
4. まとめ
- 同期処理は、進行中のタスクが終わるまで次のタスクたちは待つ方式 - 非同期処理は、進行中のタスクが終了されてない状態でも次のタスクを実行する方式 - Javascript はシングルスレッドなので、一度に一つの関数コールしか処理できない - Javascript Engine
とブラウザ(もしくは他の実行環境)が協業してマルチスレッドっぽく動いてる +)Javascript Engine だけだと非同期処理はできない
ご清聴ありがとうございました
- youtube, 「What the heck is the event loop anyway?」,
Philip Robert, https://www.youtube.com/watch?v=8aGhZQkoFbQ&t=255s, (2024.06.27) - youtube, 「개발자 90%가 모르는 자바스크립트 동작원리 (Stack, Queue, event loop)」,https://www.youtube.com/watch?v=v67LloZ1ieI&t=191s, (2024.06.27) - 이웅모, 『모던 자바스크립트 Deep Dive : 자바스크립트의 기본 개념과 동작 원리』, 위키북스 , 2020 参考資料