javascript - 有没有办法将 TimeOut 对象从对话框中的一个步骤发送到另一个步骤? - botBuilder v4 - Node.js

标签 javascript node.js botframework

在我的机器人对话步骤之一中,我在 setTimeout() 函数中启动了一些操作。 目标是在某些情况下清除其他步骤中的超时。

async saveAdults(step) {
    if (step.result) {
      step.values.adults = step.result;
      const convId = step.context.activity.conversation.id;
      const format = "dddd DD MMMM YYYY";

      // Send partial notification in case of a delay of 5 minutes
      const data = {
        checkIn: step.values.checkIn,
        nights: step.values.nights,
        adults: "",
        children: ""
      };
      const timer = await sendPartialNotification(convId, data);
      // step.values.timer = timer;
      this.notificationProp.set(step.context, timer);
      await this.conversationState.saveChanges(step.context);
    }
    return await step.next();
  }
exports.sendPartialNotification = async (convId, data) => {
  const interval = 300000;
  const timer = setTimeout(() => {
    notify(convId, this.id, data, true);
  }, interval);
  return timer;
};
async notifyClient(step) {
  const timer = this.notificationProp.get(step.context);
  clearTimeout(timer);
  // …
}

尝试将 TimeOut 对象存储在 step.values.timer 或对话状态中会引发此错误,表明无法解析 Timeout 对象...

TypeError: Converting circular structure to JSON

作为这个问题的解决方案,我正在考虑将计时器存储在Redis中..

有什么想法吗?谢谢。

最佳答案

使用状态、 Prop 或等效项将值从一个步骤传递到下一步。在下面的示例代码中,我包含一个中间步骤,询问客户端是否要取消。这纯粹是为了显示解决方案的输出。

  1. 在引导步骤中启动计时器。
async setTimer(step) {
  if (step.result) {
    const convId = step.context.activity.conversation.id;

    const data = {
      value1: someValue1,
      value2: someValue2
    };

    const timer = await sendPartialNotification(convId, data);

    this.notificationProp = { step: step.context, timer: timer };
    await this.conversationState.saveChanges(step.context);
  }
  return await step.next();
}
  • 在中间步骤中询问客户是否想要取消计时器。我把定时器设置为 10 秒。
    • 如果用户取消,计时器将被清除。
    • 如果客户端在 10 秒内拒绝或未能响应,计时器将不受影响并执行。
  • async askClient(step) {
      const timer = this.notificationProp.timer;
    
      if (timer._idleTimeout > 0) {
        const message = MessageFactory.text(
          'Cancel the timer?',
          null,
          'expectingInput'
        );
        return await step.prompt('confirmPrompt', message);
      }
    }
    
  • 最后输出结果并通知客户端。
  • async notifyClient(step) {
      const stepResult = step.result;
      step.value = { timer: this.notificationProp.timer };
    
      if (stepResult === true) {
        console.log('TIMER PRE-CLEAR ', step.value.timer);
    
        const timer = step.value.timer;
        await clearTimeout(timer);
    
        console.log('TIMER POST-CLEAR', timer);
        step.context.sendActivity('Cancelling timer');
      } else {
        step.context.sendActivity('Timer not cancelled');
      }
    
      return await step.next();
    }
    

    计时器未取消并执行:

    enter image description here

    计时器已取消:

    enter image description here

    希望得到帮助!

    关于javascript - 有没有办法将 TimeOut 对象从对话框中的一个步骤发送到另一个步骤? - botBuilder v4 - Node.js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56701822/

    相关文章:

    Javascript 函数立即停止

    javascript - 基于倒计时值动画 Raphaël JS - 类似于极地时钟

    javascript - 如何让await等待函数完成?

    javascript - 通过具有对话 ID 的 Restify API 访问特定聊天

    azure - 如何通过技能 list /端点使用 Azure Health Bot 技能?

    c# - 如何将 UserData 存储在 Bot 的复杂对象中

    javascript - Expressjs bodyParser 和连接表单

    javascript - 如何为特定的 li 添加类?

    javascript - 获取 Telegram 群的所有用户

    javascript - 如何向 NodeJS 服务器提供客户端包 (webpack)?