Help us understand the problem. What is going on with this article?

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

はじめに

今まで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を使ってシンプルな非同期処理を書いてきましょう!

参考記事

https://qiita.com/toshihirock/items/4e4231c04332c209e31d

追加

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

taqm
1児のパパです。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした