技術とか戦略とか

IT技術者が技術や戦略について書くブログです。

JavaScriptのasync・awaitのサンプルコード

JavaScriptでは、通常は非同期処理となり、重い関数が終わるまで待つということをせず、次の関数に先に制御が移ってしまいます。
そのため、API呼び出しやIO(ファイルの読み書きやDBの読み書き)を伴う関数を呼び出した後に、その結果を元に次の処理を行う、というフローを行うためには一工夫必要です。
 
これを簡単に書くために、JavaScriptにはasync/awaitという文法が用意されています。
この記事では、非同期処理のサンプルコードと、async/awaitを用いて同期処理にするサンプルコードを用意しているので、そのサンプルコードを読めば使い方は理解できると思います。
 
async/awaitを使う上での注意点として、promiseやresolve/rejectとセットで使う必要があるという点があります。
これをセットで使用しないと、同期処理にならない、待った後の処理が実行できない、等のバグになります。
async/awaitはpromiseオブジェクトを簡単に扱うための文法でもあるので、promiseについては別途調べるとより理解が深まると思います。
 
【サンプルコード(非同期処理)】
// すぐ終わる処理
function lightTask() {
 console.log("light");
}

// 1秒かかる重い処理
function heavyTask() {
 const procedure = () => {
  console.log("heavy");
 }
 setTimeout(procedure, 1000);
}

// JavaScriptは通常は非同期なので、heavyTaskの終了を待ってくれない
function exection() {
 heavyTask();
 lightTask();
}

exection();
 
【処理結果(非同期処理)】
C:\tmp>node sample.js
light
heavy

C:\tmp>
 
【サンプルコード(同期処理)】
function lightTask() {
 console.log("light");
}

function heavyTask() {
 // awaitで呼び出される関数ではpromiseオブジェクトを返す必要がある
 return new Promise((resolve, reject) => {
  const procedure = () => {
   console.log("heavy");
   resolve(0); // returnではなくresolveで戻す(これを忘れると制御が戻らない)
  }
  setTimeout(procedure, 1000);
 });
}

// awaitを使用する関数にはasyncをつける
async function exection() {
 let result = await heavyTask(); // awaitで呼び出すことで処理が終わるまで待つ
 // console.log(result); // 0
 lightTask();
}

exection();
 
【処理結果(同期処理)】
C:\tmp>node sample.js
heavy
light

C:\tmp>