LoginSignup
2
0

よく見るけどよくわからないasync/await

Last updated at Posted at 2018-12-27

はじめに

非同期処理とは?

非同期処理ってどういうこと?JavaScriptで一から学ぶ https://qiita.com/kiyodori/items/da434d169755cbb20447

Callback関数とCallback地獄

  • Callback 関数:非同期な処理が完了したら実行する関数
  • いろいろなところで使用される
    • イベントリスナ(クリックされたら〇〇を実行)
    • ファイル読み込み(ファイルを読み込んだら〇〇を実行)
    • Ajax 通信(通信が終わったら〇〇を実行)
    • などなど
  • 問題点:シンプルな処理であれば問題ないが、Callback のネストが始まると途端に辛くなる

課題1:Callbackのネストを体感する(15~25分)

  • 目的:連続した非同期処理を行いたい状況で Callback を使用すると、Callback がネストし可読性が低くなることを体感する。

  • 内容:以下の 1~3 を実現する。

    1. DynamoDB からユーザーレコードを取得する。
    これをLambdaに貼り付けてください
    const AWS = require('aws-sdk');
    const documentClient = new AWS.DynamoDB.DocumentClient({region: 'ap-northeast-2'});
    
    exports.handler = (event) => {
        console.log("[START]");
        const param1 = {
            TableName: 'async-lecture-users',
            Key: {
                userId: 'U0001',  
            },
        };
        documentClient.get(param1, (err, data) => {
            if (err) {
                console.error(err);
                return;
            }
            console.log(data);
        });
        console.log("[END]");
    };
    
    1. レコード取得処理を追加する。
    • 内容:ユーザーレコードのグループ ID をもとに、グループレコードを取得する。
    • ポイント:1.で取得したグループ ID もとに、グループレコードを取得する→documentClient.get がネストするはず!
    • 条件:
    {
        TableName: 'async-lecture-groups',
        Key: {
            groupId: data.Item.groupId, // 1.で取得したユーザーレコードのグループID
        },
    }
    
    1. さらにレコード取得処理を追加する。
    • 内容:グループレコードの平社員 ID をもとに、ユーザーレコードを取得する。
    • 条件:
    {
        TableName: 'async-lecture-users',
        Key: {
            userId: data.Item.hiraShainId, // 2.で取得したグループレコードの平社員ID
        },
    }
    

解答例

    const AWS = require('aws-sdk');
    const documentClient = new AWS.DynamoDB.DocumentClient({
      region: 'ap-northeast-2',
    });

    exports.handler = (event) => {
      console.log('[START]');
      const param1 = {
        TableName: 'async-lecture-users',
        Key: {
          userId: 'U0001',
        },
      };
      documentClient.get(param1, (err, data) => {
        if (err) {
          console.error(err);
          return;
        }
        console.log(data);

        const param2 = {
          TableName: 'async-lecture-groups',
          Key: {
            groupId: data.Item.groupId, // 1.で取得したユーザーレコードのグループID
          },
        };
        documentClient.get(param2, (err, data) => {
          if (err) {
            console.error(err);
            return;
          }
          console.log(data);

          const param3 = {
            TableName: 'async-lecture-users',
            Key: {
              userId: data.Item.hiraShainId, // 2.で取得したグループレコードの平社員ID
            },
          };
          documentClient.get(param3, (err, data) => {
            if (err) {
              console.error(err);
              return;
            }
            console.log(data);
          });
        });
      });
      console.log('[END]');
    };

Promiseの登場

Promise再入門① ~Promise基本編~ https://qiita.com/tfrcm/items/1dfe4265c36bea903ab3
Promiseについて0から勉強してみた https://qiita.com/toshihirock/items/e49b66f8685a8510bd76

課題2:CallbackのネストをPromiseで解消する(10~20分)

  • 目的:Promise を使うと、Callback のネストを解消できることを確認する。
  • 内容:課題 1.1~1.3 の内容を Promise を使って記述する。

解答例

    const AWS = require('aws-sdk');
    const documentClient = new AWS.DynamoDB.DocumentClient({
      region: 'ap-northeast-2',
    });

    exports.handler = (event) => {
      console.log('[START]');
      const param1 = {
        TableName: 'async-lecture-users',
        Key: {
          userId: 'U0001',
        },
      };

      documentClient.get(param1).promise()
          .then((data) => {
            console.log(data);
            
            const param = {
                TableName: 'async-lecture-groups',
                Key: {
                    groupId: data.Item.groupId,
                },
            };
            
            // thenブロックでPromiseをリターンすることで、次のthenの引数にデータを渡せる
            return documentClient.get(param).promise();
          })
          .then((data) => {
            console.log(data);
            
            const param = {
                TableName: 'async-lecture-users',
                Key: {
                    userId: data.Item.hiraShainId,
                },
            };
            
            return documentClient.get(param).promise();  
          })
          .then((data) => {
            console.log(data);
          })
          .catch((err) => {
            console.error(err);
          });
      console.log('[END]');
    };

async/awaitの時代

async await の使い方 https://qiita.com/niusounds/items/37c1f9b021b62194e077

課題3:async/awaitで書く(10~20分)

  • 目的:async/await を使うと簡潔に非同期処理を記述できることを確認する。
  • 内容:課題 1.1~1.3 の内容を async/await を使って記述する。

解答例

    const AWS = require('aws-sdk');
    const documentClient = new AWS.DynamoDB.DocumentClient();
    
    exports.handler = (event) => {
      console.log('[START]');
      const param1 = {
        TableName: 'async-lecture-users',
        Key: {
          userId: 'U0001',
        },
      };
    
      documentClient.get(param1).promise()
          .then((data) => {
            console.log(data);
    
            const param = {
                TableName: 'async-lecture-groups',
                Key: {
                    groupId: data.Item.groupId,
                },
            };
    
            // thenブロックでPromiseをリターンすることで、次のthenの引数にデータを渡せる
            return documentClient.get(param).promise();
          })
          .then((data) => {
            console.log(data);
    
            const param = {
                TableName: 'async-lecture-users',
                Key: {
                    userId: data.Item.hiraShainId,
                },
            };
    
            return documentClient.get(param).promise();  
          })
          .then((data) => {
            console.log(data);
            console.log('[END]');
          })
          .catch((err) => {
            console.error(err);
          });
    };
2
0
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
2
0