我使用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
消息被立即打印。是否有什么可以让我等待向导的结果的?如果没有,我该如何处理这种情况?
亲切的问候
答案 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源代码:
enter
函数。尝试在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>
enter
功能。是否值得通过自定义事件进行编辑?