JavaScript处理异步回调节点.js

时间:2018-09-07 15:20:08

标签: javascript node.js async-await webhooks async.js

我是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完成

1 个答案:

答案 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的问答。

相关问题