【问题标题】:JavaScript Handle Asynchronous Callbacks node .jsJavaScript 处理异步回调节点 .js
【发布时间】:2019-02-12 23:34:59
【问题描述】:

我是 Javascript 新手,只是被使用 Node.js 的 Javascript 异步回调卡住了。

我首先设置 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 请求。翻译 POST 请求总是在 Webhook POST 完成后执行。

有没有办法在 Webhook POST 请求完成之前在 Webhook POST 请求中执行 Translator POST 请求。

类似的东西 Webhook POST --> 执行 --> 翻译 POST 执行并完成 ---> Webhook POST 完成

【问题讨论】:

  • 如果问题不清楚请告诉我

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


【解决方案1】:

首先,languageTranslator.translate 函数是一个异步函数,因此它会返回并且不会等待回调完成。因此,如果您想确保回调完成,您应该在完成后使用新的回调或 promise.then 函数执行下一个命令。

其次,您的translatorEnglish 函数既没有callback,也没有promise。因此,没有人等待其异步函数调用 (languageTranslator.translate) 完成。因此,您应该将其更改为 promise 格式或回调格式(您也可以使用类似于 promise 的异步等待格式)。

第三,无论如何,translatorEnglish 函数将是一个异步函数,并且您想在 handle 函数的 for 循环中使用它,这意味着您可能有多个异步函数要等待,这使得它很难使用回调处理。所以我建议你在这种情况下使用承诺,为了等待所有承诺完成,你可以使用 Promise.all 函数。

别忘了,你应该让所有这些函数 promise 并在 facebook_handler().then 函数中调用 res.send

附加内容

  • 如果您想在不更改其实现(promisify)的情况下将带有回调的函数转换为 Promise,您可以使用节点 8 util.promisify 或 bluebird Promise.promisify 函数。

  • 也请看this问答。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-30
    • 2016-12-13
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2017-01-09
    相关资源
    最近更新 更多