我是Node和异步编程的新手,我已经尝试了在学习时能够更好地理解回调的所有内容。
这是一个Lex僵尸程序与Facebook集成,但我想我只是在回调地狱中迷失了。我的日志显示所有功能都正常工作,并且响应已建立并及时让Facebook不要超时,但它确实超时。所以Facebook永远不会收到回复,因此我认为回调实际上并没有达到原来的功能。
exports.handler = (event, context, callback) => {
...
// get user info from Facebook
var req = https.get('https://graph.facebook.com/v2.6/'+PSID+'?fields=first_name,last_name,gender&access_token='+pageAccessToken, (res) => {
res.setEncoding('utf8');
res.on('data', function (body) {
console.log("BODY= "+body);
body = JSON.parse(body);
event.sessionAttributes['userInfo'] = {
"first_name": body['first_name'],
"last_name": body['last_name'],
"gender": body['gender'],
"id": body['id']
};
try {
intentProcessor (event, (response) => {
console.log("RESPONSE= "+ JSON.stringify(response));
callback(null, response);
});
} catch (err) {
callback(err);
}
});
});
...
当try
位于res.on
之外时,回调会起作用并且会发送响应,但会在获取所需的用户数据之前发送。
当try
放在res.on
内时(如上面的代码所示),响应会与用户信息完美匹配。但它根本就没有回到Facebook。
有人可以解释我在处理回调时出错了吗?
答案 0 :(得分:1)
请尝试下面的代码,
exports.handler = (event, context, callback) => {
let url = `https://graph.facebook.com/v2.6/${PSID}fields=first_name,last_name,gender&access_token=${pageAccessToken}`;
// get user info from Facebook
var req = https.get(url, (res) => {
res.setEncoding('utf8');
res.on('data', function (body) {
body = JSON.parse(body);
event.sessionAttributes['userInfo'] = {
"first_name": body['first_name'],
"last_name": body['last_name'],
"gender": body['gender'],
"id": body['id']
};
intentProcessor(event, (err, response) => {
if (err) {
return callback(err);
}
return callback(null, response);
});
});
});
}
答案 1 :(得分:1)
经过长时间的调试,我发现回调和嵌套函数不是问题。原始回调在嵌套函数的任何级别都被识别。
真正的问题是Amazon Lex bot不接受sessionAttributes
内的嵌套对象或数组。
这在Lambda函数中没有错误,所以我的日志看起来很干净
删除['userInfo']
并将sessionAttributes数据存储为单个Object解决了问题。
event.sessionAttributes = {
"first_name": body['first_name'],
"last_name": body['last_name'],
"gender": body['gender'],
"id": body['id']
};
答案 2 :(得分:-1)
如果要使用响应中的数据。你将需要"承诺"。在ES7中,async / await是处理它的好方法。使用库request/request或request/promise与ES7的async / await,可以使您的代码变得更加干净。请看下面的代码。
exports.handler = (event, context, callback) => {
let data = getFacebookData();
//Do whatever you want to do using the data.
};
async function getFacebookData(){
let dataFromFacebook=await request('https://graph.facebook.com/v2.6/'+PSID+'?fields=first_name,last_name,gender&access_token='+pageAccessToken);
return JSON.parse(dataFromFacebook);
}