diff --git a/packages/core/src/session.ts b/packages/core/src/session.ts index b9337eb64..ae592790e 100644 --- a/packages/core/src/session.ts +++ b/packages/core/src/session.ts @@ -247,28 +247,38 @@ class KoishiSession { } } - async _observeChannelLike(channelId: string, fields: Iterable = []) { + async _observeChannelLike(channelId: string, fields: Iterable = [], type: 'channel' | 'guild' = 'channel') { const fieldSet = new Set(fields) const { platform } = this const key = `${platform}:${channelId}` + let cache = this[type] + if (cache) { + for (const key in cache) { + fieldSet.delete(key as any) + } + if (!fieldSet.size) return cache + } const data = await this.getChannel(channelId, [...fieldSet]) - const cache = observe(data, async (diff) => { - // https://github.com/koishijs/koishi/issues/1267 - if (data['$detached']) return - await this.app.database.setChannel(platform, channelId, diff as any) - }, `channel ${key}`) - return cache + cache = this[type] + if (cache) { + cache.$merge(data) + } else { + cache = observe(data, async (diff) => { + // https://github.com/koishijs/koishi/issues/1267 + if (data['$detached']) return + await this.app.database.setChannel(platform, channelId, diff as any) + }, `channel ${key}`) + } + return this[type] = cache as any } async observeChannel(fields: Iterable): Promise> { - const tasks = [this._observeChannelLike(this.channelId, fields)] + const tasks = [this._observeChannelLike(this.channelId, fields, 'channel')] if (this.channelId !== this.guildId) { - tasks.push(this._observeChannelLike(this.guildId, fields)) + tasks.push(this._observeChannelLike(this.guildId, fields, 'guild')) } - const [channel, guild = channel] = await Promise.all(tasks) - this.guild = guild - this.channel = channel + const [channel] = await Promise.all(tasks) return channel }