refactor(LocalDataSource, PostRepository, ChatScreen): enhance database handling and message loading
Some checks failed
Frontend CI / build-and-push-web (push) Successful in 2m41s
Frontend CI / ota-android (push) Successful in 12m45s
Frontend CI / build-android-apk (push) Has been cancelled

- Introduced a promise-based initialization mechanism in LocalDataSource to prevent concurrent initialization issues.
- Updated PostRepository to utilize an enqueueWrite method for database operations, ensuring thread-safe writes.
- Refactored ChatScreen to improve message loading logic, including preloading history and managing scroll behavior more effectively.
- Enhanced message rendering logic to maintain correct indices in inverted lists and optimize user experience during scrolling.
This commit is contained in:
lafay
2026-03-23 23:06:19 +08:00
parent 7305254e11
commit c98f1917f7
9 changed files with 396 additions and 185 deletions

View File

@@ -20,6 +20,7 @@ export class LocalDataSource implements ILocalDataSource {
private db: SQLite.SQLiteDatabase | null = null;
private dbName: string;
private initialized = false;
private initializingPromise: Promise<void> | null = null;
constructor(config: LocalDataSourceConfig = {}) {
// 如果提供了userId使用用户专属数据库
@@ -34,6 +35,21 @@ export class LocalDataSource implements ILocalDataSource {
return;
}
// 防止并发初始化导致连接状态竞争
if (this.initializingPromise) {
await this.initializingPromise;
return;
}
this.initializingPromise = this.doInitialize();
try {
await this.initializingPromise;
} finally {
this.initializingPromise = null;
}
}
private async doInitialize(): Promise<void> {
try {
// 使用全局实例管理
if (dbInstance && currentDbName === this.dbName) {
@@ -227,6 +243,17 @@ export class LocalDataSource implements ILocalDataSource {
}
return await db.runAsync(sql);
} catch (error) {
if (this.isRecoverableError(error)) {
this.db = null;
this.initialized = false;
dbInstance = null;
await this.initialize();
const db = this.ensureDb();
if (params && params.length > 0) {
return await db.runAsync(sql, params as any);
}
return await db.runAsync(sql);
}
this.handleError(error, 'RUN');
}
}

View File

@@ -195,10 +195,12 @@ export class PostRepository implements IPostRepository {
private async saveToLocalCache(post: Post): Promise<void> {
try {
await this.localDb.initialize();
await this.localDb.run(
`INSERT OR REPLACE INTO posts_cache (id, data, updatedAt) VALUES (?, ?, ?)`,
[post.id, JSON.stringify(post), new Date().toISOString()]
);
await this.localDb.enqueueWrite(async () => {
await this.localDb.run(
`INSERT OR REPLACE INTO posts_cache (id, data, updatedAt) VALUES (?, ?, ?)`,
[post.id, JSON.stringify(post), new Date().toISOString()]
);
});
} catch (error) {
console.error('[PostRepository] 保存本地缓存失败:', error);
}
@@ -210,7 +212,9 @@ export class PostRepository implements IPostRepository {
private async clearLocalCache(id: string): Promise<void> {
try {
await this.localDb.initialize();
await this.localDb.run('DELETE FROM posts_cache WHERE id = ?', [id]);
await this.localDb.enqueueWrite(async () => {
await this.localDb.run('DELETE FROM posts_cache WHERE id = ?', [id]);
});
} catch (error) {
console.error('[PostRepository] 清除本地缓存失败:', error);
}
@@ -545,7 +549,9 @@ export class PostRepository implements IPostRepository {
this.memoryCache.clear();
try {
await this.localDb.initialize();
await this.localDb.run('DELETE FROM posts_cache');
await this.localDb.enqueueWrite(async () => {
await this.localDb.run('DELETE FROM posts_cache');
});
} catch (error) {
console.error('[PostRepository] 清除所有缓存失败:', error);
}