質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Amazon DynamoDB

Amazon DynamoDBは、 AWS上のNoSQLデータベースサービスです。フルマネージド型のサービスで、スキーマレス、高速且つ安定性のある動作、自動的に容量を変更する自動スケーリングなどの特徴を持ちます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Q&A

解決済

2回答

9431閲覧

asyncの戻り値がobject Promiseになってしまう

rirako

総合スコア13

AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Amazon DynamoDB

Amazon DynamoDBは、 AWS上のNoSQLデータベースサービスです。フルマネージド型のサービスで、スキーマレス、高速且つ安定性のある動作、自動的に容量を変更する自動スケーリングなどの特徴を持ちます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

0グッド

0クリップ

投稿2020/08/24 11:21

編集2020/08/24 11:49

前提・実現したいこと

dynamoDBのクエリをlambdaで受けとりたいです。

発生している問題・エラーメッセージ

async関数list_albumsを作りDBから値を取得することはできました。
呼び出し元に値をreturnすると[object Promise]になってしまいます。
どのようにすればreturnを正常な値として受け取れるでしょうか?

result=[object Promise]

該当のソースコード

exports.list_albums =async function(body,context){ var params = { TableName: 'albums', ExpressionAttributeNames:{ '#u': 'uniqueid'}, ExpressionAttributeValues:{ ':val_1': global.userId, }, KeyConditionExpression: '#u = :val_1' }; var result =await doQuery(params); console.log('check3='+result); return result; }; function doQuery(parameter) { return new Promise((resolve, reject) => { docClient.query(parameter, (err, data) => { if (err) { console.log('[ERROR] DynamoDB Query Error: ', err); reject(err); } else { var arrstr =''; data.Items.forEach(function(album, index){ console.log(album.title); arrstr = arrstr + album.title +"\n"; console.log('check1='+arrstr); }); resolve(arrstr); } }); }); }
//呼び出し元 var result =db_control.list_albums(body,context); console.log('result='+ result); //ここが[object Promise]になる

試したこと

呼び出し元をasyncにして、呼び出しを

await db_control.list_albums(body,context);

追記

"use strict"; var AWS = require('aws-sdk'); var contents_get = require('./get_contents'); var db_control = require('./db_control'); const crypto = require("crypto"); AWS.config.region = 'ap-northeast-1'; global.messageid; global.userId; exports.handler = async function (event, context) { let body = JSON.parse(event.body); let signature = crypto .createHmac("sha256", process.env.CHANNELSECRET) .update(event.body) .digest("base64"); let checkHeader = (event.headers || {})["X-Line-Signature"]; if (signature === checkHeader) { if (body.events[0].replyToken === "00000000000000000000000000000000") { let lambdaResponse = { statusCode: 200, headers: { "X-Line-Status": "OK" }, body: '{"result":"connect check"}', }; context.succeed(lambdaResponse); // ③接続確認エラーを確認する。 } else { body.events.forEach(function(eve) { global.messageid =eve.message.id; global.userId =eve.source.userId; if (eve.message.text === 'アルバム'){ global.userId =eve.source.userId; var result =await db_control.list_albums(body); //ここのawaitがエラーになる console.log('result='+ result); } }); } } else { console.log("署名認証エラー"); } };

としてみたのですが、これはエラー(unexpectedtoken)で通りませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/08/24 11:27

呼び出し元をasyncにして、呼び出しを await db_control.list_albums(body,context); としてみたのですが、これはエラー(unexpectedtoken)で通りませんでした。 コードの一部だけ提示されてもなぜエラーになるのは判別できないので、全体を提示してください。
rirako

2020/08/24 11:50

コメントありがとうございます。 試してみた部分のコードを追記しました。 何かアドバイスなどありましたらよろしくお願いします。
guest

回答2

0

forEachの中のコールバック関数もasync関数にしてください。

diff

1"use strict"; 2var AWS = require('aws-sdk'); 3var contents_get = require('./get_contents'); 4var db_control = require('./db_control'); 5 6const crypto = require("crypto"); 7AWS.config.region = 'ap-northeast-1'; 8 9global.messageid; 10global.userId; 11exports.handler = async function (event, context) { 12 let body = JSON.parse(event.body); 13 let signature = crypto 14 .createHmac("sha256", process.env.CHANNELSECRET) 15 .update(event.body) 16 .digest("base64"); 17 let checkHeader = (event.headers || {})["X-Line-Signature"]; 18 19 if (signature === checkHeader) { 20 if (body.events[0].replyToken === "00000000000000000000000000000000") { 21 let lambdaResponse = { 22 statusCode: 200, 23 headers: { "X-Line-Status": "OK" }, 24 body: '{"result":"connect check"}', 25 }; 26 context.succeed(lambdaResponse); 27 // ③接続確認エラーを確認する。 28 29 } else { 30-- body.events.forEach(function(eve) { 31++ body.events.forEach(async function(eve) { 32 global.messageid =eve.message.id; 33 global.userId =eve.source.userId; 34 if (eve.message.text === 'アルバム'){ 35 global.userId =eve.source.userId; 36 var result =await db_control.list_albums(body); //ここのawaitがエラーになる 37 console.log('result='+ result); 38 } 39 40 }); 41 } 42 } else { 43 console.log("署名認証エラー"); 44 } 45};

投稿2020/08/24 11:56

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rirako

2020/08/25 05:51

回答ありがとうございます。 無事、エラーをとることができました。
guest

0

ベストアンサー

呼び出し元に値をreturnすると[object Promise]になってしまいます。

はい、async関数の返り値はPromiseになります。

どのようにすればreturnを正常な値として受け取れるでしょうか?

不可能です。Promiseが帰ってくることを前提に使うしかありません。

投稿2020/08/24 11:41

maisumakun

総合スコア145930

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rirako

2020/08/25 05:57

回答ありがとうございます。 戻り値を得る手段がないということはつまり、 『DBから値が返ってくるのを待つためにasyncを使う』という考え方が間違っているのでしょうか? DBからの検索結果を待ってから処理を実行する手段はありますか?
maisumakun

2020/08/25 06:40 編集

> 『DBから値が返ってくるのを待つためにasyncを使う』という考え方が間違っているのでしょうか? 合っています。そのまま普通の値として同期的に使えないというだけです。 > DBからの検索結果を待ってから処理を実行する手段はありますか? Promiseからthenでつなげる、あるいはawaitで受ける必要があります。
rirako

2020/08/25 06:44

ありがとうございます。方向性がわかって安心しました。 理解不足のため、もう一度promiseの概要から調べなおしたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問