LoginSignup
88
45

More than 3 years have passed since last update.

知らない間にAWS SDKのコールバック地獄から解放されてた (for JavaScript)

Last updated at Posted at 2018-01-23

はじめに

今までJavaScriptでaws-sdkを扱う場合は
↓こんな感じでコールバック関数を渡していました。

もともと
s3.listBuckets((err, data) => {
  if (err) {
    console.error(err);
  } else {
    console.log(data);
  }
});

簡単な処理の場合はこの書き方で良いと思うのですが
処理を手続き的に書く際にとても苦労します・・・

いわゆるコールバック地獄
dynamoDB.getItem({/*省略*/}, (err, data) => {
  if (err) {
    console.error(err); // エラーもネストの数だけハンドリングが必要
  } else {
    s3.getObject({/*省略*/}, (err, data) => {
      if (err) {
        console.error(err);
      } else {
        console.log(data);
      }
    });
  }
});

これを回避するためにasync/awaitを使おうとすると
すべてのApi呼び出しをPromiseでラップする関数を定義する必要がありました。

ラップした例
// これはこれでコールバック地獄
// しかも使用するApiの数だけ用意する・・・
function getItem(opts) {
  return new Promise((resolve, reject) => {
    dynamoDB.getItem(opts, (err, data) => {
      if (err) reject(err);
      else     resolve(data);
    });
  });
}

// メイン処理
// ここはきれいに書ける
async function hoge() {
  try {
    const res1 = await getItem({/*省略*/});
    const res2 = await getObject({/*省略*/});
    console.log(res2);
  } catch(err) {
    console.error(err); // エラーもまとめてハンドリングできる
  }
}

これを回避するためにオレオレPromisifyなども作ったりしました。

コールバック地獄にも終わりが!

最近だと↓こう記述できるとのこと

今どき
async function hoge() {
  try {
    const res1 = await dynamoDB.getItem({/*省略*/}).promise();
    const res2 = await s3.getObject({/*省略*/}).promise();
    console.log(res2);
  } catch(err) {
    console.error(err);
  }
}

見ての通りApi呼び出し後の戻り値から
そのままPromiseが返却できるらしいのです。

このpromise()関数はAWS.Requestの実装なので
例に限らずほぼ全てのAPIで使用可能だと思われます。(※ 確認したわけではありません)

まとめ

調べてみると2016年のLambdaがNode.v4対応した頃には実装されていたようですが、
公式のサンプルもコールバックを渡すプログラムになってたりするので
このpromiseの存在を知らない人もまだいるのではないでしょうか?(まさか僕だけ・・・?

ぜひPromiseを使ってシンプルな非同期処理を書いてきましょう!

参考記事

追加

気がつくと公式にページが追加されてたのでリンクしておきます

88
45
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
88
45