3.上传失败和上传中断处理
classFileStorage{ private db: IDBDatabase | null = null private dbName = 'fileStore' private storeName = 'files' private openCallback: () =>void constructor(open = () => {}) { this.openCallback = open this.openDatabase() } // 堆代码 duidaima.com // 打开或创建数据库 private openDatabase(): void { const request = indexedDB.open(this.dbName, 1) request.onupgradeneeded = (event) => { this.db = (event.target as IDBOpenDBRequest).result if (!this.db.objectStoreNames.contains(this.storeName)) { this.db.createObjectStore(this.storeName, { keyPath: 'id', autoIncrement: true }) } } request.onsuccess = (event) => { this.db = (event.target as IDBOpenDBRequest).result this.openCallback() } request.onerror = (event) => { console.error('Error opening database:', event) } } // 插入整个 fileList 数组 public async insertFileList(fileList: fileInfoWithId[]): Promise<void> { const fileContents = awaitPromise.all( fileList.map((file) =>this.readFileAsArrayBuffer(file.raw)) ) awaitthis.transaction(async (transaction) => { const objectStore = transaction.objectStore(this.storeName) for (let i = 0; i < fileList.length; i++) { const file = fileList[i] const content = fileContents[i] awaitthis.insertObjectStore(objectStore, { ...file, content }) } }) } // 插入单个 fileInfo public async insertFile(fileInfo: fileInfoWithId): Promise<void> { this.insertFileList([fileInfo]) } // 读取文件为 ArrayBuffer private readFileAsArrayBuffer(file: File): Promise<ArrayBuffer> { returnnewPromise((resolve, reject) => { const reader = new FileReader() reader.readAsArrayBuffer(file) reader.onload = () => resolve(reader.result asArrayBuffer) reader.onerror = (error) => reject(error) }) } // 插入对象到 objectStore private async insertObjectStore( objectStore: IDBObjectStore, file: fileInfoWithId & { content: ArrayBuffer } ): Promise<void> { returnnewPromise((resolve, reject) => { const request = objectStore.add(file) request.onsuccess = () => resolve() request.onerror = (error) => reject(error) }) } // 根据 ID 列表删除数据 public async deleteByIds(ids: number[]): Promise<void> { awaitthis.transaction(async (transaction) => { const objectStore = transaction.objectStore(this.storeName) for (const id of ids) { const request = objectStore.delete(id) awaitthis.waitForRequest(request) } }) } // 根据单个 ID 删除数据 public async deleteById(id: number): Promise<void> { awaitthis.transaction(async (transaction) => { const objectStore = transaction.objectStore(this.storeName) const exists = awaitthis.checkIfExists(objectStore, id) if (!exists) { console.warn(`No file found with id ${id}`) return } console.log(`Deleting file with id ${id}`) const request = objectStore.delete(id) awaitthis.waitForRequest(request) }) } // 检查是否存在指定 ID 的数据 private async checkIfExists( objectStore: IDBObjectStore, id: number ): Promise<boolean> { returnnewPromise((resolve) => { const getRequest = objectStore.get(id) getRequest.onsuccess = () => { resolve(getRequest.result !== undefined) // 如果 result 是 undefined,说明没有找到该 ID } getRequest.onerror = (error) => { console.error('Check existence error:', error) resolve(false) } }) } // 查找所有数据 public async findAll(): Promise<fileInfoWithId[]> { returnawaitthis.transaction(async (transaction) => { const objectStore = transaction.objectStore(this.storeName) const request = objectStore.getAll() returnawaitthis.waitForRequest(request) }) } // 清空整个对象存储中的所有数据 public async clearDatabase(): Promise<void> { awaitthis.transaction(async (transaction) => { const objectStore = transaction.objectStore(this.storeName) const request = objectStore.clear() awaitthis.waitForRequest(request) console.log('Database cleared successfully') }) } // 带分页的查找功能 public async findWithPagination( page: number, pageSize: number ): Promise<fileInfoWithId[]> { returnawaitthis.transaction(async (transaction) => { const objectStore = transaction.objectStore(this.storeName) const start = (page - 1) * pageSize const result: fileInfoWithId[] = [] let currentIndex = 0 const cursorRequest = objectStore.openCursor() returnnewPromise<fileInfoWithId[]>((resolve, reject) => { cursorRequest.onerror = (error) => reject(error) cursorRequest.onsuccess = (event) => { const cursor = (event.target as IDBRequest).result if (cursor) { if (currentIndex >= start && currentIndex < start + pageSize) { result.push(cursor.value) } if (currentIndex < start + pageSize) { currentIndex++ cursor.continue() } else { resolve(result) } } else { resolve(result) } } }) }) } // 创建事务并执行回调 private async transaction<T>( callback: (transaction: IDBTransaction) =>Promise<T> ): Promise<T> { returnnewPromise((resolve, reject) => { if (!this.db) { reject(newError('Database not initialized')) return } const transaction = this.db.transaction([this.storeName], 'readwrite') callback(transaction).then(resolve).catch(reject) transaction.oncomplete = () => { console.log('Transaction completed') } transaction.onerror = (error) => { console.error('Transaction error:', error) reject(error) } }) } // 等待请求完成 private waitForRequest<T>(request: IDBRequest<T>): Promise<T> { returnnewPromise((resolve, reject) => { request.onsuccess = () => resolve(request.result) request.onerror = (error) => { console.error('Request error:', error) reject(error) } }) } } exportdefault FileStorage并发任务控制
classconcurrencyControl{ private maxConcurrency: number private queue: any[] private running: number private onAllTasksCompleted: Function constructor( maxConcurrency: number, onAllTasksCompleted: Function = () => {} ) { this.maxConcurrency = maxConcurrency this.queue = [] this.running = 0 this.onAllTasksCompleted = onAllTasksCompleted } addQueue(queue: Function[]) { this.queue.push(...queue) this.run() } addTask(task: Function) { this.queue.push(task) this.run() } run() { while (this.running < this.maxConcurrency && this.queue.length) { this.running++ const task = this.queue.shift() Promise.resolve(task()).finally(() => { this.running-- this.run() if (this.running === 0 && this.queue.length === 0) { this.onAllTasksCompleted() } }) } } } exportdefault concurrencyControl