はじめに
非同期処理について再確認するために記事をまとめました。
結構馴れ馴れしい感じの説明になっておりますが、ご愛嬌ということで、お許しください。
非同期処理とは?
一般的な説明
通常のプログラムって実行すると、コードを上から順に1行ずつ実行していきますよね。重いfunctionだったり、sleep(5000);とかだったら待たないと処理が終わることができません。非同期で処理をした方が効率が良い時があっても同期で処理がされていきます。それを解決してくれる処理が非同期処理です。
非同期処理は、文字通り非同期に処理ができます。例えば、10秒かかるfunctionがあったとしてそのレスポンスを待っている間に違うfunction処理を実行することができます。
レンチンが基本の一人暮らしの男性の自炊に例えると
「セブンイレブンのレンチンでできるホルモン焼き丼・豚汁」という献立だとします。
まず一番時間がかかるのは炊飯する白米ですよね。40分ぐらいかかるので、一番最初に処理を開始いたします。その間、豚汁を作ります。人参きったり、豚肉きったり...味付けしたり。
で、豚汁作業中に白米が終わりセブンのレンチンホルモンをレンジに入れます。豚汁終了とタイミングにホルモンを白米の上にのせ丼が完成、豚汁をよそい食卓に並べれば完成。
わざわざ炊飯中になにもやらないでじっと待つことはないですよね...
コードに例えると
律儀に炊飯中はじっと待つタイプの方のコード
console.log("start");
function chouri(name ,milliSeconds) {
var startTime = new Date().getTime();
while (new Date().getTime() < startTime + milliSeconds);
console.log(name + "終了");
}
chouri('炊飯', 2400); // 白米を炊飯するのに40分かかる
chouri('豚汁', 1200); // 豚汁を作るのに20分かかる
chouri('レンチンホルモン', 120); // レンチンホルモンに2分かかる
console.log("end");
これは通常通り、上から下に実行されます。
ログは以下の通りです。
start
// 40分後
炊飯終了
// 20分後
豚汁終了
// 2分後
レンチンホルモン終了
end
全ての調理が終わるのに、1時間2分かかります。
今度は効率の良い調理コード
console.log("start");
function suihan() {
return new Promise(resolve => {
setTimeout(() => {
console.log('炊飯終了');
}, 2400);
});
}
function tonjiru() {
return new Promise(resolve => {
setTimeout(() => {
console.log('豚汁終了');
}, 1200);
});
}
function horumon() {
return new Promise(resolve => {
setTimeout(() => {
console.log("レンチンホルモン終了")
}, 120);
});
}
async function chouri() {
await Promise.all([suihan(), tonjiru(), horumon()]);
}
console.log("start");
chouri()
console.log("end");
こちらのコードは同タイミングで処理がされていきます
ログは以下の通りです。
start
end
// 2分後
レンチンホルモン終了
// 20分後
豚汁終了
// 40分後
炊飯終了
これを処理すると、40分で調理が終わります。
ただ、注意としてはレンチンホルモンは冷めてます。
まとめ
手際の良い主婦の調理フローをコードに落とし込むのは至難の技ということにしましょう。
これが非同期処理です。