Top View


Author Takehiro Tada

ちゃんとTypeScriptでasync/awaitを書く

2020/12/16

非同期処理を順序よく出力する

よくある非同期処理の説明で活用されるパターンのサンプルです。

const outputText = (str: string): Promise<any> => {
  console.log("waiting...");
  const returnPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(`Message: ${str}`);
      resolve();
    }, 5000);
  });
  return returnPromise;
};

console.log("count 1");
outputText("hogehoge");
console.log("count 2");

この実行結果は

count 1
waiting...
count 2
Message: hogehoge

となります、これを順序よく出力するように修正してみましょう。

とりあえず、先ほどのコードの outputText メソッドの呼び出し部分を少し手直ししてみます。

const outputText = (str: string): Promise<any> => {
  console.log("waiting...");
  const returnPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(`Message: ${str}`);
      resolve();
    }, 5000);
  });
  return returnPromise;
};

console.log("count 1");
outputText("hogehoge").then(() => {
  console.log("count 2");
});

すると、とりあえず期待する答えが返ってきます。

count 1 
waiting... 
Message: hogehoge 
count 2 

これをasync/awaitを使うと気持ち綺麗にかけます。

const outputText = (str: string): Promise<any> => {
  console.log("waiting...");
  const returnPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(`Message: ${str}`);
      resolve();
    }, 5000);
  });
  return returnPromise;
};

const func = async () => {
  console.log("count 1");
  await outputText("hogehoge");
  console.log("count 2");
};

func();

知っとるわ!!!!!

と思ったあなたは、おそらく普段から非同期処理を書いている人です。

async functionの応用

さて、基本的なasync/awaitの書き方を書いて行きましたが、ここからは応用テクニックです。

関数としての利用

当たり前ですがasync functionは関数であるため、関数としての利用が可能です。具体的には、「引数としての利用」「if文の活用」「返り値の結果を代入」などがあります。

const func = async () => {
  // 引数としての利用
  barFunc(await fooFunc());

  // if文としての利用
  if (await fooFunc().length) {
  }

  // 返り値を変数に代入して利用
  const response = await fooFunc();
};

HTTPリクエストとasync/await

async/awaitが生きてくる場面の1つとして、HTTPリクエストが挙げられます。axiosを例にtry/catchにてしっかりハンドリングしてみます。

import axios from "axios";

const callAxios = async () => {
  // 市町村APIを試しに利用
  const url: string =
    "https://opendata.resas-portal.go.jp/api/v1/cities?prefCode=1";
  try {
    const response = await axios.get(url);
    const data = response.data;
    console.log(data);
  } catch (error) {
    console.error(error.message);
  }
};

callAxios();

async/awaitやっぱり便利ですね、積極的に使って行きましょう。

Takehiro Tada

Takehiro Tada

よくTypeScript書いてる人