【问题标题】:Read from DynamoDB with Lambda nodejs for Alexa Skill使用 Lambda nodejs 从 DynamoDB 读取 Alexa Skill
【发布时间】:2018-05-05 23:36:30
【问题描述】:

我是 Skill 和 nodejs 开发的新手,很快就遇到了我的第一个问题。

基本上,我正在尝试从 DynamoDB 读取数据并让它通过 Alexa 说话。

var title;

exports.handler = (event, context, callback) => { 
    getData();
    alexa = Alexa.handler(event, context, callback); 
    alexa.appId = APP_ID;
    alexa.registerHandlers(handlers);
    alexa.execute();     
};

const handlers = {
    'LaunchRequest': function () {
        this.emit('DoSomethingIntent');
    },
    'DoSomethingIntent': function () {      
        this.response.speak('Here are your data ' + title);
        this.emit(':responseReady');        
    },
};

function getData() {
    var ddb = new AWS.DynamoDB.DocumentClient({region:'eu-west-1'});
    var params = {
        TableName: 'data', 
        Key: {'data_id' : 1,},
    };      
    ddb.get(params, function(err, data) {
        if (err) {
        }else{
           title = data.Item.title;             
        }
    });
}

问题在于 DynamoDB.DocumentClient.get 函数异步运行,同时 DoSomethingIntent 运行时标题变量未定义。

解决此问题的最佳做法是什么?

到目前为止,唯一对我有用的解决方案是:

ddb.get(params, function(err, data) {
    if (err) {

    }else{
        title = data.Item.title;                                      
        alexa.registerHandlers(handlers);
        alexa.execute(); 
    }
});

但对我来说似乎不太实用!

【问题讨论】:

  • DoSomethingIntent Intent 中调用get 方法。
  • 那不行。 ddb.get(params, function(err, data) { });异步运行。
  • 'DoSomethingIntent': function () { getData(callback(title) { this.response.speak('Here are your data ' + title); this.emit(':responseReady'); } ) }
  • 谢谢@PriyamGupta 就是这样!

标签: javascript node.js amazon-dynamodb aws-lambda alexa


【解决方案1】:

您的工作解决方案是正确的,因为如果您编写执行逻辑,那么它将在完成 Dynamodb 回调之前运行。请记住 DynamoDB 调用是异步非阻塞 I/O,因此它不会阻塞任何代码在回调之外执行。所以添加 Alexa 执行逻辑的更好的地方是在回调内部。

【讨论】:

    【解决方案2】:

    发生这种情况是因为ddb.get() 函数是异步的,并且回调在您的处理程序执行后运行。因此,在发送您的响应之前,不确定变量 title 是否会被填充。

    你可以在这里使用原生承诺。

    如下修改你的 getData 函数:

    function getData() {
      var ddb = new AWS.DynamoDB.DocumentClient({region:'eu-west-1'});
      var params = {
          TableName: 'data', 
          Key: {'data_id' : 1,},
      };
    
      return new Promise((resolve,reject) => {
        ddb.get(params, function(err, data) {
            if (err) {
            }else{
              title = data.Item.title;
              resolve(title);       
            }
        });
      })
    }
    

    并在您的处理程序函数和响应处理程序中进行以下更改:

    exports.handler = (event, context, callback) => { 
        // Remove getData() from here
        alexa = Alexa.handler(event, context, callback); 
        alexa.appId = APP_ID;
        alexa.registerHandlers(handlers);
        alexa.execute();     
    };
    
    const handlers = {
        'LaunchRequest': function () {
            this.emit('DoSomethingIntent');
        },
        'DoSomethingIntent': function () {
          getData()
          .then( (title) => {
            this.response.speak('Here are your data ' + title);
            this.emit(':responseReady'); 
          })
          .catch( (error) => { // Handler error gracefully
            console.log(error);
            this.response.speak('Something is wrong. Try later.')
            this.emit(':responseReady');
          })
        },
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-23
      • 1970-01-01
      • 2019-11-09
      • 2020-09-13
      • 2020-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多