🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

4回答

5066閲覧

javascriptでどれが非同期処理なのかが分かりません

umashiba

総合スコア13

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

1グッド

2クリップ

投稿2019/02/19 23:15

編集2019/02/20 00:31

javascriptにおいてsetIntervalやsetTimeout等は非同期処理に分類されるというのが分かるのですがそのほかの非同期処理にはどのようなものがあげられるのかわからない為、どの処理にPromise等を使えばよいのか分かりません。

例えば、

javascript

1const root = document.getElementById('root'); 2console.log('test');

のようなコードを例として挙げると

もし
const root = document.getElementById('root')
が5000msかかるとても重い処理だった場合でも
console.log('test')
は実際に5000ms後に実行されるのかが
const root = document.getElementById('root')
が非同期処理かが分からない為判断ができません。
なのでどの処理が非同期処理として扱われるのか教えていただきたいです。
よろしくお願いします。

退会済みユーザー👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

4つに大別しました。

  • HTTPリクエスト系 (XHR, fetch, ajax)
  • アニメーション系
  • イベント系 (DOM Events)
  • タイマー系 (setTimeout, setInterval)

率直にいって、全てを覚えているわけではありません。
基本的に、時間のかかる処理処理時間が他の要素に依存する処理(回線速度やHDDの読み込み速度など)を同期処理にしてしまうと処理待ちの時間が多くかかるので、非同期処理になるという考えで良いと思います。

Re: nannan1 さん

投稿2019/02/20 00:25

think49

総合スコア18189

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

umashiba

2019/02/20 00:45 編集

回答いただきありがとうございます。ネット上を探してもsetIntervalとsetTimeoutしか具体例を見つけることができなかったのでとても助かりました。ベストアンサーに選ばせていただきます。
guest

0

ドキュメントを参照して、「コールバックが定義されているか否か」である程度は判別できます。

  • 定義されている: 非同期処理の可能性がある
  • 定義されていない: 確実に同期処理

このように覚えておけば大丈夫です。
定義されている場合、コールバックの第一引数がエラー(err)であるかで判別できます。

  • 第一引数がerrである: 確実に非同期処理
  • 第一引数がerrではない: ドキュメントを読んで判断しよう

JavaScriptの公式リファレンスはECMAScriptですが超絶読みづらいので、
Firefox作ってる団体が管理しているMDNで調べると良いでしょう。

ライブラリは各種ライブラリが提供している公式のドキュメントやリファレンスを閲覧してください。
なければソースコードを直接読んでください。
Qiitaや各種ブログは鵜呑みにしないようにしてください、侍エンジニア○塾のブログなんてもっての他です。


実はコールバックを定義する同期処理というのは書こうと思えば書けます。

JavaScript

1// これは同期処理なのでコールバックを使うだけ無駄 2var testFunction = function (cb) { 3 console.log('test'); 4 cb(); 5} 6testFunction(function () { 7 console.log('done'); 8}) 9// test -> doneの順番に表示

JavaScript

1// え?なんで?こう書けば2行で収まるでしょ? 2console.log('test'); 3console.log('done');

という訳で、コールバックというのは冗長になるので定義するだけ無駄です。
はーつっかえ、やめたら?この書き方!

なので理由が無い限り使わない。
これが大原則です。


JavaScriptはシングルスレッドなので並列処理が出来ません。
また、JavaScriptは実行中、ブラウザの動作を完全に停止させる仕様です。
その間ブラウザがフリーズしたかのように応答しなくなってしまいます。

特にHDDやネットワーク通信のような遅い通信はJavaScriptとは完全に無関係な所で時間を使います。
先方の都合もあり完了時刻が読めません。
その間ブラウザはフリーズしっぱなしかよ、ユーザビリティ悪くなるじゃん。

そこでイベントという概念で解決します。

イベント置き場に、「達成条件」と「実行したい処理を包んだ関数」を1セットで登録します。
JavaScriptはイベント登録を受理すると、暇な時に「完了したイベントは無いかな〜?」と巡回して、
達成したイベントが存在するときに、対になっている関数を取り出して実行してくれます。

例えばAjax通信でHTTPリクエストを送信するとHTTPレスポンスが帰ってくるまで暇になります。
JavaScriptの担当領域が終わったら「HTTPレスポンスが帰ってきたら」をトリガーにイベント登録を行い処理を終了させます。
実際にHTTPレスポンスが帰ってきたら関数化した残りの処理を行います。

これによりブラウザがHTTPレスポンス待ちの間ずっと操作を受け付けずフリーズするのを回避しているわけですね。


const root = document.getElementById('root')

復習を兼ねて回答します。

JavaScriptのビルトイン機能ですね。
コールバックをくださいとは言っていませんね?
なのでこれは検討するまでもなく「同期処理」です。

DOM APIを使ったDOM操作は基本的にJavaScriptの管轄として扱われるので、
確かにDOMの構成をドラスティックに変更してしまうのは超重いのですが、
これはしょうがない、払うべきコストなので非同期処理ではなく同期処理なのです。

コールバックを定義されているのに同期処理ってもしかしたらあるんじゃないの?

あります。
公開関数と呼ばれるものがその代表例です。

Array.prototype.mapがその象徴です。

JavaScript

1[1, 2, 3].map(function (num) { return num + 2 }); 2// [3, 4, 5]

配列のビルトインメソッドに集中しているイメージがありますが、
map, filter, sort, reduce…を始めとするロジックを注入するものは例外としてコールバックを定義されているのに非同期ではありません。

投稿2019/02/20 01:27

編集2019/02/20 02:13
miyabi-sun

総合スコア21203

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miyabi-sun

2019/02/20 02:14

よく考えたらコールバックのありなしだけでは見分けられませんでした。 まぁ、コールバックが無いと非同期処理は絶対に実現不可なのである程度は判別出来るのでその方向で路線変更しました。
umashiba

2019/02/20 02:25

丁寧に回答いただきありがとうございました。callbackがあるかないかでjavascript本体でもライブラリでもある程度見分けることができるという方法、ライブラリ等を使っていて非同期なのか同期なのかわからない事が数多くあったため大変参考になりました。早速この方法活用していきたいと思います。
think49

2019/02/20 03:32

> 「コールバックが定義されているか否か」 現状、非同期処理完了を検知する手段がコールバック関数、awaitぐらいしか選択肢がないので、筋の良いAPIなら、コールバック関数が用意されているのは事実です。 ただ、XHRはイベントで待ち受けるので、「リクエスト実行関数」と「完了を待ち受ける関数」が別であり、後発のFetch APIもメソッドチェーン上で完了を待ち受け出来るものの「実行と完了は別関数」という事実は変わりません。 リファレンスを読めば分かりますが、設計思想を読みとらないと、該当場所を探し当てるのに苦労するかもしれません。 ちなみに、イベントとPromiseは思想こそ違うものの、どちらもコールバックで完了を検知しています。 > Array.prototype.mapがその象徴です。 関数型プログラミングの代表である「配列系統の繰り返し処理」は同期処理という覚え方になりますかね…。
think49

2019/02/20 03:33 編集

二重投稿の為、削除
umashiba

2019/02/20 11:55

非同期処理はコールバック関数による制御の他にもイベントを用いて別関数で制御をする場合もあるということですね。補足いただきありがとうございます。加えて「配列系統の繰り返し処理」という覚え方、とても覚えやすいです。こちらも教えていただきありがとうございました。
guest

0

Qiitaの JavaScriptの同期、非同期、コールバック、プロミス辺りを整理してみる というページが、同期・非同期処理について良く整理されていて、コード例も示されているので判りやすいと思います。
お勧めです。

=補足 質問で求められているのが「ネット上の様々な記事でsetIntervalを使った例は良く見たが実際、setInterval以外に非同期処理として扱われる処理(関数)にはどのような物があるのか具体例を知りたい」ということだったので=

Aの処理が終わったら、Bの処理を始めて、Bの処理が終わったら、Cの処理を始めて、、、、というように前の処理が終わった時(期)と同じくして次の処理を始めるのが「同期」、それ以外の時に処理を始めるのが「非同期(同期じゃない)」です。
Javascriptで非同期に処理を開始するタイミングとして使えるものが2種類あります。一つ目はタイマー(目覚まし時計を仕掛けるような感じ)、二つ目はイベント(ユーザによる操作、(ネットワーク等を経由した)外部からの働きかけ)です。
前者はsetIntervalを使って設定し、後者はaddEventListnerを使って設定します。これらは、非同期処理の開始タイミングを設定する関数(処理)です。
関数の実行が同期か非同期かは、連続した処理の一環で行われるか、タイマーやイベントのタイミングで行われるかの違いです。1つの関数が同期的に実行されたり、非同期的に実行されたりする事はありえます(引用したQiitaの記事の console.log等)

投稿2019/02/19 23:28

編集2019/02/20 01:46
coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

umashiba

2019/02/20 00:07

回答いただきありがとうございます。紹介してくださった記事読ませていただきました。記事自体分かりやすくて大変参考なりました。しかしこの質問の意図として「ネット上の様々な記事でsetIntervalを使った例は良く見たが実際、setInterval以外に非同期処理として扱われる処理(関数)にはどのような物があるのか具体例を知りたい」といったニュアンスで質問させていただきました。もしよろしければ非同期処理として扱われる具体的な処理を教えていただけないでしょうか。
umashiba

2019/02/20 00:39

申し訳ございません。別の方の回答をベストアンサーに選ばせていただきました。お手数おかけいたしました。
umashiba

2019/02/20 01:58

補足いただきありがとうございます。javascriptではタイマーとイベントが非同期として扱われるのですね。理解する事ができました。コメントでの要望に応えていただきありがとうございました。
guest

0

クライアントのいわゆるブラウザで動く話と推測して、非同期の古くからある典型は、サーバーへの問い合わせ、だと思います。

投稿2019/02/20 00:21

papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

umashiba

2019/02/20 00:46

回答いただきありがとうございます。参考にさせていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問