スタック・オーバーフロー Asked by masaru.morita on November 17, 2021
PollyでMP3を作成してからS3にアップロードし、URLを返すLambdaを、別のLambdaから呼び出しているのですが、呼び出し先のレスポンスを待たずに呼び出し元のLambdaが先に完了してしまします。呼び出し先のLambdaによるMP3作成は、呼び出し元が完了後に完了する動きになってしまっています。
呼び出し先のLambdaのレスポンスを待ってから、呼び出し元のLambdaを完了させるにはどうすればよいでしょうか。
■呼び出し元のLambda
var lambda = new AWS.Lambda({apiVersion: '2015-03-31'})
exports.handler = function(event, context, callback){
res = invokeCreateMp3()
console.log(res) //undefinedになる
}
function invokeCreateMp3(name, sec) {
lambda.invoke({
FunctionName: 'create_mp3_for_timer',
InvocationType: 'RequestResponse',
Payload: '{ "name":"kana", "sec":3 }',
}, function(error, data) {
if (error) {
console.log("error:" + error)
} else {
console.log("response:" + data)
}
});
}
■呼び出し先のLambda
var polly = new AWS.Polly({apiVersion: '2016-06-10'});
var s3 = new AWS.S3({apiVersion: '2006-03-01'});
exports.handler = function(event, context, callback) {
var url = createMp3(event.name, event.sec);
var res = {
"statusCode": 200,
"headers": { "Additional-Headr1": "1234" },
"body": JSON.stringify({"response":"response", "event":event, "url":url}),
};
callback(null, res);
};
function createMp3(name, sec) {
var ssml = '<speak><break time="' + sec +'s" />' + name +'タイマーは終わりです。</speak>';
var buket = 'mp3_buket';
var key = name + '_' + sec + 's.mp3';
var url = 'https://s3-ap-northeast-1.amazonaws.com/' + buket + '/' + key;
let speechParams = {
OutputFormat: 'mp3',
VoiceId: 'Mizuki',
Text: ssml,
SampleRate: '22050',
TextType: 'ssml'
};
polly.synthesizeSpeech(speechParams).promise().then((data) => {
console.log(data); // successful response
// s3にPutする用のパラメータ
var s3Params = {
ACL: 'public-read', //S3権限
Bucket: buket,
Key: key,
ContentType: 'audio/mp3',
Body: new Buffer(data.AudioStream) // AudioStreamの取得
};
// s3にputする
s3.putObject(s3Params, (err) => {
if (err) {
console.log(err);
} else {
console.log('Success');
}
});
}, (error) => {
console.log("Failure!", error);
});
return url;
}
呼び出し元がコールバックを待つ実装になっていないようです。
動作確認まではできていないのですが、こんな感じに修正すれば同期的に実行できるのではないでしょうか。
var lambda = new AWS.Lambda({apiVersion: '2015-03-31'})
exports.handler = async function(event, context, callback){
res = await invokeCreateMp3()
console.log(res) //undefinedになる
}
async function invokeCreateMp3(name, sec) {
try {
const data = await lambda.invoke({
FunctionName: 'create_mp3_for_timer',
InvocationType: 'RequestResponse',
Payload: '{ "name":"kana", "sec":3 }',
}).promise();
console.log("response:" + data);
return data;
} catch (error) {
console.log("error:" + error);
return error;
}
}
Answered by Bladean Mericle on November 17, 2021
nodejsにあまり詳しくないので、外しているかもしれませんが、まずinvokeCreateMp3は非同期で動作すると思うので、promiseを返すなどして終了待機をする必要があるのでは?
同様にcreateMP3の部分も。
putObjectもpromiseを使う必要があるかと思います。
Answered by Hattori Makoto on November 17, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP