对于 dispose 事件的疑问 & 如何在应用退出时保留数据

  ctx.on('dispose', () => {
    console.log('_____________________')
    p.save() // 具体使用了 ctx.database.upsert 这个方法
  })

我尝试使用dispose事件保存我插件的数据,但是发现数据还是丢失了,console.log 这个函数也没有在终端上留下任何痕迹。

我是使用 ctrl + c 的方式关闭程序,是我退出程序的方法有误?还是我对这个事件所代表的含义理解产生了错误?

如果是这样,请问正确的退出方式和对应的保存数据方法是什么?

1 个赞

dispose 事件用于回收插件的副作用,而不是确保数据保存。

dispose 事件确定会被触发的时机包括:

  • 插件被停用
  • 插件依赖的服务被移除或替换

dispose 事件不一定会触发的时机包括:

  • Koishi 崩溃
  • Koishi 被强行中断

为了保护你的数据,你应该在每一次修改后保存而不是在 dispose 中保存。如果你担心数据更新过于频繁,可以设置一个防抖的推送逻辑:

const update = debounce(10000, () => {
  p.save()
})

然后在每一次数据更改后调用 update()

2 个赞

上一楼的补充说明:

Q:为什么 dispose 事件在某些时机不会触发?
A:因为 dispose 事件的目的是回收副作用。回收副作用的意义是防止行为注册多次和内存泄漏等问题。在整个 Koishi 进程中断的情况下,我们是不需要担心上述问题的。

Q:那有办法让 dispose 事件能在进程中断时触发吗?
A:没有完美的方法。我们确实可以在很多场景下增加 dispose 的支持,但有一种情况是无论如何都无法确保执行的,那就是 Koishi 崩溃。因此,我们无论如何都不建议使用 dispose 保存数据。

1 个赞

这里文档确实没有说明 dispose 未触发的情况,我会更新一下。感谢你的问题。

2 个赞

我同样感谢您的解答,谢谢。

1 个赞

原来是这样的,学到了