问题
I am new to Node.js and Javascript and am developing an Alexa application using Lambda function and DynamoDB.
I have a table in DynamoDB named: Chat
with PrimaryKey: 'Said' and a column 'say'. Whenever the Alexa skills is launched I just want to fetch a record based on what is said by the user and return. So its basically a single Query on the primary key which works fine.
However, I dont get any response from the lambda function in speech output variable as the API doesn't wait for the response builder to complete the async call to DynamoDB and returns a null response.
Is there any way to enforce the async call to be resolved before sending the response?
const WelcomeMessage = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'LaunchRequest' ||
(request.type === 'IntentRequest');
},
handle(handlerInput) {
var ans;
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({
region: 'us-east-1'
});
// Create the DynamoDB service object
var dynamodb = new AWS.DynamoDB();
var params = {
TableName: 'chat',
Key: {
'said': {
S: 'Hi Sir' + ''
}
},
ProjectionExpression: 'say'
};
dynamodb.getItem(params, function(err, data) {
if (err) {
console.log(err, err.stack);
} else {
if (data) {
return handlerInput.responseBuilder
.speak(data.Item.say.S + '')
.getResponse();
} else {
ans = 'You dint train me for that!';
return handlerInput.responseBuilder
.speak(ans)
.getResponse();
}
}
});
}
};
Wrong Output:
回答1:
I found a workaround. I return a promise and resolve it before I return it ensuring the callback to be completed before a response is sent.
const WelcomeMessage = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'LaunchRequest'
|| (request.type === 'IntentRequest');
},
handle(handlerInput) {
return new Promise((resolve) => {
var ans;
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'us-east-1'});
// Create the DynamoDB service object
//ddb = new AWS.DynamoDB({apiVersion: '2012-10-08'});
var dynamodb = new AWS.DynamoDB();
var params = {
TableName : 'chat',
Key: {
'said':{S: handlerInput.requestEnvelope.request.intent.slots.input.value+''}
}
};
dynamodb.getItem(params, function(err, data) {
if (err){
console.log(err, err.stack);
}
else{
if(data.Item){
return resolve(handlerInput.responseBuilder
.speak(data.Item.say.S+'')
.withShouldEndSession(false)
.getResponse());
}
else{
ans='You dint train me for that!';
return resolve(handlerInput.responseBuilder
.speak(ans)
.withShouldEndSession(false)
.getResponse());
}
}
});
});
}
};
来源:https://stackoverflow.com/questions/51957527/alexa-custom-skill-dynamodb-node-js-responsebuilder-not-waiting-for-async-call-t