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
我的 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