※このブログではサーバー運用、技術の検証等の費用のため広告をいれています。
記事が見づらいなどの問題がありましたらContactからお知らせください。


【TypeScript】コールバックAPIの実装をPromiseで再定義

TypeScript Type GeoLocationAPI 非同期 Promise コールバック地獄

投稿日:2021年4月24日

このエントリーをはてなブックマークに追加
この記事ではコールバックAPIの実装をPromiseでラップする方法について、実践のコードを交えて詳しく解説しています。

はじめに

この記事について

一部のブラウザAPIはcacllbackAPIとして書かれている場合があります。それらAPIをそのまま利用してしまうとコードブロックが非常に複雑になってしまうことがあります。
そのような場合にはPromiseで再定義することでよりシンプルで汎用的なコードにすることができます。
この記事ではコールバックAPIをPromiseでラッピングする方法について解説しています。

環境について

この記事は以下の環境で確認しました。

  • typescript version 4.2.4

tsconfig.json
{
  "compilerOptions": {
    "target": "ES2015",
    "module": "ESNext",
    "lib": ["ES2018", "DOM"],
    "strict": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}

Promise関数の作成

Promise関数は初期化コンストラクタの第1引数の関数の呼び出しが処理の正常終了、第2引数の関数が処理のエラー終了を意味します。
それではためしにコールバックAPIで実装されているGeoLocationAPIをPromiseで書いて見ましょう。

/**
 * 現在の位置を取得するブラウザAPIの呼び出し( Promise )
 */
const getCurrentPositionAsPromise = (): Promise<GeolocationPosition> => {
  const promise = new Promise<GeolocationPosition>((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(
      (success) => {
        resolve(success);
      },
      (error) => {
        reject(error);
      }
    );
  });
  return promise;
};

// サンプル実行
getCurrentPositionAsPromise()
  .then((value) => {
    const latLng = {
      lat: value.coords.latitude,
      lng: value.coords.longitude,
    };
    console.log(latLng);
  })
  .catch((err) => {
    alert(err);
  });

ここでPromiseの初期化時にGenericsで型を指定している点に注目してください。今回はgetCurrentPosition()の成功時コールバックで渡される予定の値の型GeolocationPositionを指定しています。

Promise<T>()Tを指定せずobjectを生成することもできるのですが、その場合Promiseのインスタンスメソッドthen()で渡される値がany型になってしまいます。
TypeScriptを使用するのであればコード上の型はできるだけ厳密に決めるべきでしょう。

このエントリーをはてなブックマークに追加


関連記事

記事へのコメント