今日は非同期処理について復習をしたので、まとめてみることにします!
通常上から下へ処理が実行されるのが、プログラミングのルールですが、意図的に順番を変えたり、実行を遅延させることが出来、それらを総称して**「非同期処理」**と言います!
利用するケースの一例は下記の通りです。
・ネットワークを経由したリクエスト全般
・意図的に遅延させた処理
・ファイルの読み込みや書き込み
複数の処理を同時並行的に行えることが最大のメリットです!
簡単な例を以て実験してみましょう。
console.log("最初の処理");
function callback() {
console.log("一番最後の処理");
}
setTimeout(callback, 3 * 1000);
//3秒後に関数callbacl()を呼び出す処理
console.log("次の処理");
//結果は下記になります。
//最初の処理
//次の処理
//一番最後の処理
以上のように、本来上から下へ行われるはずのプログラムの処理の順番を変えることが出来ました!
ちなみに処理を遅らせるときによく使う文法はこちら
・setTimeout → 引数で指定した時間後に一度だけ実行。
・setInterval → 因数で指定した間隔で、処理を繰り返し実行する。繰り返しを止めるときはclearIntervalを使用。
let count = 0;
function timeCount() {
count++;
console.log(count);
}
let sum = setInterval(function() {
timeCount();
if (count === 10) {
// 10になったら処理をストップする。
clearInterval(sum);
}
}, 1 * 1000); //1秒ごとに数字をカウント。
// 結果
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
// 10
プロミスを使ってみよう
Promiseとは非同期処理をシンプルに記述する方法です。(階層と処理が複雑になっていくいわゆるコールバック地獄を防ぐことが可能)
先ず新しいPromiseのインスタンスを生成し、関数呼び出しの際にthenメゾットを用いることで処理を分岐させたり、処理の終了を指定することが出来ます。
function eatApple(apple) {
return new Promise(function(onFulfilled, onRejected) {
//成功(onFulfilled)と失敗(onRejected)で処理を分ける
for (let i = apple; i >= 0; i--) {
setTimeout(function() {
//setTimeoutをここで利用。時間差を生み出します。
if (i > 0) console.log(i);
else onFulfilled("お腹いっぱい!");
}, (apple - i) * 1000); //処理する間隔の時間を指定
}
});
}
eatApple(5).then(
function() {
//成功(onFulfilled)した時の処理
console.log("ごちそうさまでした!");
},
function(err) {
//失敗(onRejected)した時の処理
console.log("もう食えんわ・・・");
}
);
//結果 1秒ごとに表示されます
// 5
// 4
// 3
// 2
// 1
// ごちそうさまでした!
async/awaitを使ってみよう
非常に便利なPromiseですが、ES2017以降さらに便利にさらに短く書くことが出来ます。
async → 関数の前に付けることで、必ずPromiseを返すようになる。
await → async関数の中でのみ実行。thenメソットのような働きをする。
async function eatApple(apple) {
await new Promise((onFulfilled, onRejected) => {
//成功(onFulfilled)と失敗(onRejected)で処理を分ける
for (let i = apple; i >= 0; i--) {
setTimeout(function() {
//setTimeoutをここで利用。時間差を生み出します。
if (i > 0) console.log(i);
else onFulfilled("お腹いっぱい!");
}, (apple - i) * 1000); //処理する間隔の時間を指定
}
});
//awaitで囲んだnew Promise内の処理が完了したら実行
try {
console.log("ごちそうさまでした!");
} catch {
console.log("もう食えんわ・・・");
}
}
//async関数を呼び出し
eatApple(5);
//結果 1秒ごとに表示されます
// 5
// 4
// 3
// 2
// 1
// ごちそうさまでした!
以上が非同期処理のまとめでした。
どんどん書いて慣れていきたいと思います!
それでは、また。