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
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
22
TypeScript のコンパイル
gardensky511
0
66
【2025年新卒研修】 React・Next.js は何であるのか
gardensky511
0
140
Webレンダリング最適化の道
gardensky511
0
57
Webレンダリング技術の進化と課題
gardensky511
0
100
Promise と async/await
gardensky511
0
63
集合で理解する Typescript
gardensky511
1
340
Javascript のデータ型 プリミティブ型・オブジェクト
gardensky511
0
180
Other Decks in Programming
See All in Programming
その問い、本当に正しいですか?AI時代のエンジニアに必要な哲学と認知科学 / ai-philosophy-cognitive-science
minodriven
11
6.1k
技術的負債解消で開発者の未来を開く- AIの力でコード刷新
kmd2kmd
0
110
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
290
Lemonade + Foundry Toolkit でお手軽アプリ開発
seosoft
1
370
Oxlintのカスタムルールの現況
syumai
6
1.1k
肥大化するレガシーコードに立ち向かうためのインターフェース分離と依存の逆転 / JJUG CCC 2026 Spring
hirokunimaeta
0
600
ADKを使って簡単にAIエージェントを作ってみよう
k1mu21
0
280
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5.3k
Webフレームワークの ベンチマークについて
yusukebe
0
180
A2UI という光を覗いてみる
satohjohn
1
150
RTSPクライアントを自作してみた話
simotin13
0
620
AIを活用したE2Eテスト実装効率化のあゆみ / ebisu-mobile-14-kotetu
kotetuco
0
130
Featured
See All Featured
How to build a perfect <img>
jonoalderson
1
5.7k
KATA
mclloyd
PRO
35
15k
Deep Space Network (abreviated)
tonyrice
0
210
A Soul's Torment
seathinner
6
3k
Writing Fast Ruby
sferik
630
63k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
580
A better future with KSS
kneath
240
18k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.7k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
2
870
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
400
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Amusing Abliteration
ianozsvald
1
210
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 参考資料