Alexa Custom Skill DynamoDB.Node.js ResponseBuilder Not waiting for Async Call to complete

冷暖自知 提交于 2019-12-11 16:57:14

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!