alexa 说不能使用 promise、rest 和 dynamodb 组合

alexa say is not working with promise, rest and dynamodb combination

我的 alexa 应用程序有问题。我对 NodeJS 和 Alexa 还很陌生,

这是我的问题。我有一个包含数组的 dynamodb。从该数组中,我将从一个为我提供 JSON 数据的休息网站获取我的所有值。我会将这些数据传递给模板,最后调用 alexa say 命令。

出于某种原因,一切正常,除了 say 部分。

我绝对希望你能阐明我所缺少的东西。

代码如下:

    app.intent('sayStockList', {
        'utterances': ['{|say stock list}']
      },
      function(req, res) {
        var stockInfoHelper = new StockInfoDataHelper();
        var currentUserId = req.userId;
        databaseHelper.readCodeList(currentUserId).then(function(currentJsonData) {
          var currentData = [];
          var toSay = '';
          console.log("1) Current Data= %j", currentJsonData);
          if (undefined === currentJsonData) {
            toSay = 'You don\'t have any code stored. To store a code say: Alexa, add code.';
          } else {
            currentData = currentJsonData['data'];
            return Promise.all(currentData.map(fn)).then(function(returnString) { //fn all return correctly
              console.log("2) Promise return : %s", returnString);
              res.say(returnString.toString()).shouldEndSession(false).send();
            }).catch(function(err) {
              console.log("3) Error: %s", err);
            });
          }
        }); // Promise readCodeList then end
        console.log("4) TEST 12 ");
        return true;
      }
    );// end app intent

这是日志输出:

    4) TEST 12 
    1) Current Data= {"data":["data1","data2"],"userId":"xxxxxx"}
    Function getDataValue
    Function getDataValue
    2) Promise return : Return value for data1.  Return value for data2

感谢您的帮助!

伊恩-雷米

我终于找到了诺言的解决方案。

据我了解,res.say 操作在 promise 实现之前就已经消耗掉了。使用 Q 框架,我能够在 promise 之后延迟 res.say 的消费。 (不确定我这里的词汇是否正确,请随时纠正我!)

此外,如果您有任何不同的做法,请随时告诉我。

这是更正后的代码

var q = require('q');

...

app.intent('sayStockList', {
    'utterances': ['{|say stock list}']
    },
      function(req, res) {
          var stockInfoHelper = new StockInfoDataHelper();
          var currentUserId = req.userId;
          var qPromise = q.defer(); //  <--  Added this line here
          databaseHelper.readCodeList(currentUserId).then(function(currentJsonData) {
              var currentData = [];
              var toSay = '';
              console.log("1) Current Data= %j", currentJsonData);
              if (undefined === currentJsonData) {
                  toSay = 'You don\'t have any code stored. To store a code say: Alexa, add code.';
              } else {
                  currentData = currentJsonData['data'];
                  return Promise.all(currentData.map(fn)).then(function(returnString) { //fn all return correctly
                      console.log("2) Promise return : %s", returnString);
                      res.say(returnString.toString()).shouldEndSession(false).send();
                      qPromise.resolve();  // <--  When this is called, the res.say is working
                  }).catch(function(err) {
                      console.log("3) Error: %s", err);
                  });
              }
          }); // Promise readCodeList then end
          console.log("4) TEST 12 ");
          return qPromise.promise; <--- From my understanding, this is added to make the alexa app wait for the promise resolve.  
      }
    );// end app intent

这里有更多信息 What $q.defer() really does?

您还可以在此处阅读 q 文档:
https://docs.angularjs.org/api/ng/service/$q
http://devdocs.io/q/

Fadeout79

基于理解...

  • app.intent回调应该return<promise>,而不是true
  • You don\'t have any code stored ... 消息不应悬置

...以下重写会更有意义:

app.intent('sayStockList', {
    'utterances': ['{|say stock list}']
}, function(req, res) {
    return databaseHelper.readCodeList(req.userId)
//  ^^^^^^
    .then(function(currentJsonData) {
        console.log("1) Current Data= %j", currentJsonData || null);
        if (!currentJsonData || !currentJsonData.data || currentJsonData.data.length === 0) { // better safety
            return 'You don\'t have any code stored. To store a code say: Alexa, add code.';
        //  ^^^^^^
        } else {
            return Promise.all(currentJsonData.data.map(fn))
            .then(function(results) {
                console.log("2) Promise return : %s", results.toString());
                return results.toString();
            //  ^^^^^^
            });
        }
    })
    .then(function(sayString) { // `sayString` is either the results or the `'You don\'t have any code stored. ...'` message.
        res.say(sayString).shouldEndSession(false).send();
    })
    .catch(function(err) {
        console.log("3) Error: %s", err);
        res.say('Sorry, something went wrong').shouldEndSession(false).send(); // keep user informed.
    });
}); // end app intent