##はじめに
####学習するに至った経緯
2020年より、未経験からエンジニアへの転職を目指し、某プログラミングスクールへ通う。入学後、『Ruby』を未経験から学ぶ人が多いのと『Ruby』の求人が思っていた以上に少ないので、卒業後、フロントエンドのエンジニアを目指す事に。
Javascriptの学習した事を言語化し、認識の深化による備忘録として記載。
##非同期処理とは
『非同期処理』とは実行した処理の完了を待たずに次の処理を実行する動きのこと。
逆に『同期処理』は実行した処理の完了を待って次の処理を実行する動きのこと。
##非同期処理が発明された経緯
① 今までは、普通にプログラムを書いていた。
例:データを取ってきて、処理をする。
getData('url'); ⇦ 処理が完了してから、次の行の処理へ移行する。
show();
② 上記のプログラムだとデータが取り終わるまで、画面が表示されないという問題が起きる。
理由:通常、プログラムが上から順に実行されるから。
getData('url'); ⇦ 処理が完了してから、次の行の処理へ移行する。
show();
③ バックグラウンドで処理を行う事を発明した。
先に画面を表示しておいて、データを取り終えると該当の画面を表示する。
⇨ 画面が真っ白な状態を防ぎ、ユーザーを待たせる事がない。
####※ 処理を一度バックグラウンドに移して別の処理を先に行い、処理を完了したら、内容を反映させる = 非同期処理
##非同期処理の実現
① コールバック関数を使う
sample.jsは、『setTimeoutが第2引数1000ms (=1秒)を取る。1秒後に、関数1(console.log(1))の処理を行う。』というプログラム。
####※ 引数を取る関数のことをコールバック関数という。コールバック関数を使うと非同期にして、処理のタイミングをずらす。
setTimeout(() => console.log(1), 1000);
console.log(2);
//処理を実行
2
<・undefined
> 1
####⇨ コールバック関数の非同期処理を順々に実行するのが複雑だと判明。
setTimeout(() => console.log(3), 1000);
setTimeout(() => console.log(2), 1000);
setTimeout(() => console.log(1), 1000);
//処理を実行
< 5762
3
2
1
>
上記のサンプルコードだと1秒後に一斉に表示されるが、順に実行される訳ではない。1秒ずつ、順に実行しようとすると下記のコードになる。※ コードが複雑で読みづらい。
setTimeout(() => {
console.log(3);
setTimeout(() => {
console.log(2);
setTimeout(() => {
console.log(1);
}, 1000);
}, 1000);
}, 1000);
//処理を実行
< 4034
3
2
1
>
② Promiseを使う
####『Promise』の特徴
(1) 連続した非同期処理をフラットに書ける
(2)『後で値を返すから待つ』という約束
(3) 状態を待つ
『Promise』の基本
//最初は『待つ』状態
new Promise(() => {});
//resolveすると『完了した』状態
new Promise(resolve => resolve() => {});
//完了時の値をthenで繋げて次の処理を渡せる
new Promise(resolve => resolve('こんにちは') =>
.then(res => console.log(res));
sample.jsをcount.jsへ書き換えると下記のようになる。
※ thenで繋げるとソースコードが見づらい。
new Promise(resolve => {
setTimeout(() => {
console.log(3);
resolve();
},1000)
}).then(() => {
return new Promise(resolve => {
setTimeout(() => {
console.log(2);
resolve();
},1000);
});
}).then(() => {
return new Promise(resolve => {
setTimeout(() => {
console.log(1);
resolve();
},1000);
});
});
③ async/awaitを使う
複雑ではなく、普通に書けるようにする。
func = async() => { //関数に対してasyncと宣言 ➡︎『この関数は非同期関数』
await log(3);
await log(2);
await log(1); //関数の呼び出し前にawait
}; //⇨ Promiseの結果が返って来るまで待つ
log = (num) => { //Promiseを返す関数
retrun new Promise(resolve => {
setTimeout(() => {
console.log(num);
resolve();
}, 1000);
});
}
func();
##① コールバック関数
[JavaScriptを基本からまとめてみた【15】【コールバック関数】]
(https://qiita.com/kanfutrooper/items/a8f8c60aea11f1b81086)
##② Promise
[JavaScriptを基本からまとめてみた【14】【Promise】]
(https://qiita.com/drafts/c31c9b357fc6200c485e/edit)
##③ 「async/await」
[JavaScriptを基本からまとめてみた【16】【async / await】]
(https://qiita.com/kanfutrooper/items/c71b17d312a7ea53b009)
##参考サイト
[JavaScriptの非同期処理を同期させる方法【初心者向け】]
(https://www.otwo.jp/blog/asynchronous-processing/)
[小学生でもわかるasync/await/Promise入門【JavaScript講座】]
(https://www.youtube.com/watch?v=kbKIENQKuxQ&t=421s)