refactor(LocalDataSource, PostRepository, ChatScreen): enhance database handling and message loading
- 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:
@@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user