Azure Bot NodeJS:如何等待其他对话框执行完成?
我懂你现在的困扰——调用session.beginDialog("getRequiredInformations")后,后面的session.send直接就执行了,完全不等对话框收集完用户信息,对吧?这是因为beginDialog是异步启动对话框的,它不会卡住后续代码的执行,所以你的消息会在对话框还在和用户交互时就发出去了。
要解决这个问题,我们可以利用Bot Framework的瀑布流特性,或者通过对话框结束后的回调来处理,下面给你两种实用的方案:
方案1:用瀑布流步骤等待对话框结束
把intent1的处理改成瀑布流形式,第二个步骤会自动等待第一个步骤里启动的对话框完成后再执行:
var intents = new builder.IntentDialog({ recognizers: [recognizer] }) .matches('intent1', [ // 第一步:启动收集信息的对话框 (session, args, results) => { session.beginDialog("getRequiredInformations"); }, // 第二步:对话框完成后执行后续逻辑 (session, results) => { // 这里可以拿到对话框返回的结果(如果有返回的话) session.send("I received your information"); } ]);
同时,你需要确保getRequiredInformations对话框在信息收集完成后正确结束,比如用session.endDialog()或者session.endDialogWithResult()返回收集到的数据:
bot.dialog('getRequiredInformations', [ (session) => { // 第一个提问,比如获取姓名 builder.Prompts.text(session, "Could you tell me your name?"); }, (session, results) => { // 保存姓名后继续提问,最后结束对话框并返回数据 session.userData.username = results.response; builder.Prompts.number(session, "And your age?"); session.endDialogWithResult({ response: session.userData }); } ]);
当getRequiredInformations调用endDialogWithResultfirst碧-strD
然后 Convers男女抛亲>>!
rata:用户信息会被传递到intent1瀑布流第二个步骤的results.response里,你可以直接用它来丰富回复内容。
方案2:使用beginDialog的回调函数
如果你不想用瀑布流,也可以给beginDialog传递一个回调函数,这个函数会在对话框结束后触发:
var intents = new builder.IntentDialog({ recognizers: [recognizer] }) .matches('intent1', (session, args, results) =>{ session.beginDialog("getRequiredInformations", {}, (err, result) => { // 对话框结束后执行这里的逻辑 if (!err) { session.send("I received your information"); // 如果有返回结果,也可以在这里使用:result.response } }); });
这个方式同样需要你在getRequiredInformations对话框中正确调用endDialog或endDialogWithResult,否则回调函数不会被触发。
总结一下核心思路:别在beginDialog之后直接写后续逻辑,而是把后续逻辑放在瀑布流的下一个步骤,或者beginDialog的回调函数里,这样就能确保代码等待对话框完成后再执行啦。
内容的提问来源于stack exchange,提问作者fsulser

