是否可以等待WizardScene?

时间:2019-06-09 21:22:27

标签: javascript node.js telegram telegram-bot

我使用TelegrafJS开发了一种用于Telegram的机器人,而且我还在使用TelegrafInlineMenu库来处理菜单布局。

我已经注册了一个WizardScene来验证用户输入,这里是代码:

const WizardScene = require('telegraf/scenes/wizard');
const Stage = require('telegraf/stage');
const projectController = require('../controllers/project.controller');

module.exports = function(bot) {

  const projectNameWizard = new WizardScene('projectName-wizard',
    (ctx) => {

      ctx.reply(ctx.i18n.t('projectName'));
      ctx.scene.session.project = {};

      //Project updating
      ctx.scene.session.project.oldName = ctx.match[1];

      //Keep customer reference
      ctx.scene.session.project.customerId = ctx.update.callback_query.from.id;
      return ctx.wizard.next();
    },
    async(ctx) => {

      //Get the name of the projec
      let oldPrName = ctx.scene.session.project.oldName;
      let newPrName = ctx.message.text;

      //Convalidate project
      if (ctx.message.text.length < 1 || ctx.message.text.length > 12) {
        return ctx.reply(ctx.i18n.t('invalidProjectName', {
          "characters": 12
        }));
      }
      ctx.scene.session.project.name = ctx.message.text;

      //Update the project fields
      await projectController.SaveProject(ctx.scene.session.project, ctx.update.message.from);
      let pr = await projectController.DisplayProjectDetails(ctx, newPrName);

      ctx.scene.leave();

      //Project was updated
      if (oldPrName !== undefined) {

        ctx.reply(ctx.i18n.t('projectUpdated'));
      }

      return pr;
    }
  );

  const stage = new Stage([projectNameWizard]);
  stage.command('cancel', (ctx) => {

    ctx.reply(ctx.i18n.t('operationCanc'));
    return ctx.scene.leave();
  });
  bot.use(stage.middleware())
}

要在菜单中启动向导,请使用以下代码:

projectEdit.simpleButton(ctx =>
  ctx.i18n.t('editName'), 'EDIT_PR_NAME', {
    doFunc: async ctx => {
      await ctx.scene.enter('projectName-wizard');
      console.log("hello world");
    },
  });

我需要等待WizardScene完成,然后执行console.log;。问题是await前面的ctx.scene.enter没有等待,并且hello world消息被立即打印。是否有什么可以让我等待向导的结果的?如果没有,我该如何处理这种情况?

亲切的问候

1 个答案:

答案 0 :(得分:0)

  

”“我需要等待WizardScene的完成,然后执行console.log,问题是ctx.scene.enter前面的await没有等待任何内容,并且打印了hello world消息

     
      
  • 是否可以让我等待向导的结果?

  •   
  • 如果没有,我还能如何处理这种情况?”

  •   

我不使用Telegraf,但如果每次尝试均失败,则可以考虑使用自定义事件来通知WizardScene准备就绪。它可能会帮助您解决“您好世界被立即打印出来……”

的问题。

而不是准备await或场景,而要监听准备就绪的通知(事件)。转到使场景“就绪”的代码部分,然后从那里调度一个事件以通知代码处理已完成。

自定义事件的基本示例:

<!DOCTYPE html>
<html>
<body>

<script>

//# define Event
var myReadyEvent = new CustomEvent("evt_WizardIsReady");

//# create Event handling function
function doWizardIsReady(evt)  
{ 
    alert("Got Event... : " + evt.type);
    console.log("hello world");
}

//# some function to trigger Event
function doSomething() 
{
    //# eg: prepare your scene here 

    //# and then dispatch at end of setup (before any RETURNs)
    document.body.dispatchEvent( myReadyEvent );
}

document.body.addEventListener("evt_WizardIsReady", doWizardIsReady, false);
setTimeout(doSomething, 6000); //represents waiting time for WIzardScene to be ready...

</script>

</body>
</html>

查看您的代码...

您要执行以下操作:document.body.dispatchEvent( myReadyEvent );

  • return pr;

  • 行之前
  • 或在行bot.use(stage.middleware())

  • 之后

或者,考虑编辑Telegraf源代码:

尝试在return handler(this.ctx, noop)行之前调度事件。

document.body.dispatchEvent( myReadyEvent );
return handler(this.ctx, noop)

然后在主要的HTML代码(加载所有这些外部JS文件)中,您可以收到如下所示的调度事件:

<body>

<script type="text/javascript" src="context.js"></script>

<script>

//# define Event
var myReadyEvent = new CustomEvent("evt_WizardIsReady");
document.body.addEventListener("evt_WizardIsReady", doWizardIsReady, false);

//# create Event handling function
function doWizardIsReady(evt)  
{ 
    alert("Got Event... : " + evt.type);
    console.log("hello world");
}

</script>

</body>
  • 另请参阅:stage.js-检查第37行的enter功能。是否值得通过自定义事件进行编辑?