投稿日:2021年4月24日
この記事ではコールバックAPIの実装をPromiseでラップする方法について、実践のコードを交えて詳しく解説しています。
一部のブラウザAPIはcacllbackAPIとして書かれている場合があります。それらAPIをそのまま利用してしまうとコードブロックが非常に複雑になってしまうことがあります。
そのような場合にはPromiseで再定義することでよりシンプルで汎用的なコードにすることができます。
この記事ではコールバックAPIをPromiseでラッピングする方法について解説しています。
この記事は以下の環境で確認しました。
{
"compilerOptions": {
"target": "ES2015",
"module": "ESNext",
"lib": ["ES2018", "DOM"],
"strict": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
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を使用するのであればコード上の型はできるだけ厳密に決めるべきでしょう。