我是Java的新手,只是使用Node.js进行Java异步回调。
我首先设置Facebook Webhook并发出Webhook POST请求
这是我的代码: routes.js
**To set up facebook webhook**
var facebook_handler = require('../controllers/botkit').handler
module.exports = function (app) {
// public pages=============================================
// root
app.get('/', function (req, res) {
res.render('home')
})
app.get('/webhook', function (req, res) {
// Check to see which webhook password (FACEBOOK_VERIFY_TOKEN) to check for, from incoming request.
if (process.env.PORT ||process.env.VCAP_APP_PORT ) {
FB_VERIFY_TOKEN = process.env.FACEBOOK_VERIFY_TOKEN
} else {
FB_VERIFY_TOKEN = process.env.FACEBOOK_VERIFY_TOKEN_DEV
}
// This enables subscription to the webhooks
if (req.query['hub.mode'] === 'subscribe' && req.query['hub.verify_token'] === FB_VERIFY_TOKEN) {
res.send(req.query['hub.challenge'])
}
else {
res.send('Incorrect verify token')
}
})
app.post('/webhook', function (req, res) {
console.log("\n CALL HANDLER FUNCTION ---- \n");
facebook_handler(req.body)
console.log("call handler done");
res.send('okay')
})
}
从上述代码中,我向Facebook webhook发出POST请求并获取FB消息的详细信息,然后在另一个文件BotKit.js中处理webhook POST请求
Botkit.js
var request = require('request');
require('dotenv').load();
var handler = function (obj) {
console.log("Message received from FB \n");
if (obj.entry ) {
for (var e = 0; e < obj.entry.length; e++) {
for (var m = 0; m < obj.entry[e].messaging.length; m++) {
var facebook_message = obj.entry[e].messaging[m]
test_message = facebook_message.message.text;
translatorEnglish (test_message) // calling the watson translator api to get translation for the received facebook message.
}
}
}
上面的代码处理webhook POST请求并调用Translator函数(翻译POST请求)
翻译器功能
var translationusername = "1234"
var translationpassowrd = "1234"
var transURL = "https://gateway.watsonplatform.net/language-
translator/api/v2/translate";
translatorEnglish = function(test_message) {
console.log("this should be called when translator called:" +test_message);
var parameters = {
text: test_message,
model_id: 'es-en'
};
languageTranslator.translate(
parameters,
function(error, response, body) {
if (error)
console.log(error)
else
english_message = response.translations[0].translation
console.log("The response should be:" +english_message);
translate = false
//console.log(JSON.stringify(response, null, 2));
}
);
};
问题是直到呼叫处理程序即webhook POST请求完成后,翻译POST请求才执行。 Webhook POST完成后,翻译POST请求总是执行。
在Webhook POST请求完成之前,有什么方法可以在Webhook POST请求中执行Translator POST请求。
像这样的事情 Webhook POST->执行->翻译POST执行并完成---> Webhook POST完成
答案 0 :(得分:-1)
首先,languageTranslator.translate
函数是一个异步函数,因此它返回并且不等待回调完成。因此,如果您要确保回调已完成,则应在回调完成后通过使用新的回调或promise.then函数执行下一个命令。
第二,您的translatorEnglish
函数既没有callback
,也没有promise
。因此,没有人等待其异步功能调用(languageTranslator.translate
)完成。因此,您应该将其更改为promise格式或回调格式(也可以使用类似于promise的async await格式)。
第三,无论如何,translatorEnglish
函数将是一个异步函数,并且您想在handle
函数的for循环内使用它,这意味着您可能要等待多个异步函数,这使得使用回调很难处理。因此,我建议您在这种情况下使用诺言,为了等待所有诺言完成,您可以使用
Promise.all功能。
别忘了,您应该使所有这些函数都承诺并在res.send
函数中调用facebook_handler().then
。
附加:
如果要转换带有回调的函数以承诺而不更改其实现(承诺),则可以使用节点8 util.promisify或bluebird Promise.promisify函数。
也来看看this的问答。