はじめに
非同期処理とは?
非同期処理ってどういうこと?JavaScriptで一から学ぶ https://qiita.com/kiyodori/items/da434d169755cbb20447
Callback関数とCallback地獄
- Callback 関数:非同期な処理が完了したら実行する関数
- いろいろなところで使用される
- イベントリスナ(クリックされたら〇〇を実行)
- ファイル読み込み(ファイルを読み込んだら〇〇を実行)
- Ajax 通信(通信が終わったら〇〇を実行)
- などなど
- 問題点:シンプルな処理であれば問題ないが、Callback のネストが始まると途端に辛くなる
課題1:Callbackのネストを体感する(15~25分)
-
目的:連続した非同期処理を行いたい状況で Callback を使用すると、Callback がネストし可読性が低くなることを体感する。
-
内容:以下の 1~3 を実現する。
-
- 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]"); };
-
- レコード取得処理を追加する。
- 内容:ユーザーレコードのグループ ID をもとに、グループレコードを取得する。
- ポイント:1.で取得したグループ ID もとに、グループレコードを取得する→documentClient.get がネストするはず!
- 条件:
{ TableName: 'async-lecture-groups', Key: { groupId: data.Item.groupId, // 1.で取得したユーザーレコードのグループID }, }
-
- さらにレコード取得処理を追加する。
- 内容:グループレコードの平社員 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);
});
};