Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(async): 同期処理と非同期処理 #503

Merged
merged 20 commits into from
Jun 29, 2018
Merged

feat(async): 同期処理と非同期処理 #503

merged 20 commits into from
Jun 29, 2018

Conversation

azu
Copy link
Collaborator

@azu azu commented Jun 25, 2018

#94

  • 同期処理
  • 非同期処理
  • [コラム] JavaScriptはメインスレッドで実行される(もっといいタイトル?)
  • 非同期処理と例外

@bot-user
Copy link

bot-user commented Jun 25, 2018

Deploy preview for js-primer ready!

Built with commit 2a75dcb

https://deploy-preview-503--js-primer.netlify.com

@azu azu mentioned this pull request Jun 25, 2018
4 tasks
@azu
Copy link
Collaborator Author

azu commented Jun 25, 2018

#94 を更新して大雑把な分類をつけた。
この分類ごとにPRを出していくのがいいかな。

// 重たい処理の例として10の6乗コの要素を持つ配列を0に初期化し返す
function createLargeArray() {
console.log("重たい処理を実行します");
return new Array(10e6).fill(0);
Copy link
Collaborator Author

@azu azu Jun 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この重たい処理をブラウザを固めない程度で、実行環境にばらつきがない感じのいい感じのやつないかなー

10e6 意外一瞬で終わる…
10e7だとおもすぎる

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0以外でfillするとかフィボナッチ数列をつくるとか

```

同期処理は直感的な処理順ですが、このような重たい処理や終わるかわからない処理がある場合に問題となります。
特にブラウザにおいては、このような重たい同期処理はブラウザの体感への悪影響を与えるため問題となりやすいです。
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このような重たい

このようなを連呼シすぎている

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

悪影響を与えるため問題となりやすいです。

悪影響を与えるためです。


基本的には非同期処理も同期処理と同じようにメインスレッドで実行されます。
非同期処理は名前から考えるとメインスレッド以外で実行されるように見えますが、
非同期処理がどのようにメインスレッドで実行されているかを簡潔に見ていきます。
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なんかここの流れが無理やりな感じ

また、`setTimeout`関数でタイマーに登録した次の行で重たい処理を実行しています。

`setTimeout`関数による非同期処理がメインスレッドとは異なるスレッドで実行されてるならば、
コールバック関数はメインスレッドの重たい処理の影響は受けないはずです。
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ほとんど受けない?ぐらいにしておく?


`setTimeout`関数による非同期処理がメインスレッドとは異なるスレッドで実行されてるならば、
コールバック関数はメインスレッドの重たい処理の影響は受けないはずです。
しかし、実際にはメインスレッドの重たいの影響を受けるため、タイマーに登録した時間より遅れて非同期でコールバック関数が呼び出されます。
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

重たいの影響を

処理が抜けている


JavaScriptでは一部の例外を除き非同期処理が**平行(concurrent)**して処理されます。

ECMAScriptの仕様では**JobQueue**と呼ばれるキューで次の行うタスクが管理されています。
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

次に行う

ECMAScriptの仕様では**JobQueue**と呼ばれるキューで次の行うタスクが管理されています。
次に処理するタスクをキューから1つ取り出し、タスクの処理が終わったら次のタスクを取り出りだすというのを繰り返してプログラムを評価しています。

同期処理では、キューにタスクを追加せずに、次々と処理するということを繰り返しています。
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

次々と処理するということを繰り返しています。

現在ある処理を次々と処理しています。

これによって、非同期処理のタスクが重たい同期の処理によって実行が遅れるという現象を引き起こします。
そのためJavaScriptの非同期処理も基本的には1つのメインスレッドで処理されていると考えても間違いよいでしょう。

ただし、非同期処理の中にも例外的にメインスレッドとは別のスレッドで実行できるAPIが実行環境で提供されている場合があります。
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

冗長な感じ

そのためJavaScriptの非同期処理も基本的には1つのメインスレッドで処理されていると考えても間違いよいでしょう。

ただし、非同期処理の中にも例外的にメインスレッドとは別のスレッドで実行できるAPIが実行環境で提供されている場合があります。
たとえばブラウザでは[Web Worker][] APIはメインスレッド以外でJavaScriptを実行できため、非同期処理を**並列(Parallel)**に処理できます。
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Web Worker][] APIはメインスレッド以外でJavaScriptを実行できため

[Web Worker][] APIを使いメインスレッド以外でJavaScriptを実行できため

console.log("この文は実行されます");
```

コード的には`try`ブロックの中で、`setTimeout`関数によってタイマーへコールバック関数が登録されます。
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここ1行減らせそう


このような非同期処理では、setTimeoutの内側の例外をキャッチできますが、setTimeoutの外側からは例外は発生したかわかりません。

JavaScriptでは、この非同期処理と例外処理を扱う方法としてさまざまなパターンが存在しています。
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この非同期処理と例外処理

この非同期処理での例外処理を扱

// 重たい処理の例として10の6乗コの要素を持つ配列を0に初期化し返す
function createLargeArray() {
console.log("重たい処理を実行します");
return new Array(10e6).fill(0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0以外でfillするとかフィボナッチ数列をつくるとか

しかし、`createLargeArray`関数は1000万回の`0`を代入するという重たい処理です。(実際にどの程度が重たいかは実行する端末の性能で変化します)
そのため、`createLargeArray`関数を呼び出すとその処理が完了するまで、次の処理(次の行)が呼ばれません。
次のコードの`doHeavyTask`関数では1000万回の`0`を代入するという**重たい処理**を意図的に行っています。(実際にどの程度が重たいかは実行する端末の性能で変化します)そのため、`doHeavyTask`関数を呼び出すとその処理が完了するまで、次の処理(次の行)が呼ばれません。
`Date.now`メソッドで時間を取得し、**重たい処理**がどの程度処理をブロッキングしているかを計測しています。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

何のために計測するかボケている気がします

しかし、`createLargeArray`関数は1000万回の`0`を代入するという重たい処理です。(実際にどの程度が重たいかは実行する端末の性能で変化します)
そのため、`createLargeArray`関数を呼び出すとその処理が完了するまで、次の処理(次の行)が呼ばれません。
次のコードの`doHeavyTask`関数では1000万回の`0`を代入するという**重たい処理**を意図的に行っています。(実際にどの程度が重たいかは実行する端末の性能で変化します)そのため、`doHeavyTask`関数を呼び出すとその処理が完了するまで、次の処理(次の行)が呼ばれません。
`Date.now`メソッドで時間を取得し、**重たい処理**がどの程度処理をブロッキングしているかを計測しています。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

何のために計測するかボケている気がします

@azu
Copy link
Collaborator Author

azu commented Jun 28, 2018

重たい処理じゃなくて wait 関数みたいのを作ればいいことに気づいた。

@azu
Copy link
Collaborator Author

azu commented Jun 29, 2018

"重たい処理" を "同期的にブロックする処理" とするようにして、実装もsleep関数みたいなのにした。
ちょっと冗長担った気はする

@azu azu merged commit f44fbae into master Jun 29, 2018
@azu azu deleted the sync-async branch June 29, 2018 03:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants