使用JsStore从IndexedDB查询时IDBKeyRange仅方法执行错误求助
让我们一步步分析并解决你遇到的两个错误:
一、1.3.0版本的"Failed to execute 'only' on 'IDBKeyRange'"错误
这个错误的核心原因是查询条件的值与数据库中存储的字段类型不匹配,或者JsStore旧版本处理简单对象形式的Where条件时存在bug。
排查与解决方案:
确认数据类型一致性
检查你存入IndexedDB的ChildName字段是否确实是string类型。比如如果存入时不小心把ChildName存成了number或null,而查询时传入的是字符串(如"India"),IDBKeyRange就会判定参数不是合法键,抛出该错误。
你可以通过JsStore的count方法快速验证类型:this._connection.count({ From: this._indexedDBLiveDBTableName, Where: Where('ChildName').typeIs('string') }).then(count => { console.log('合法的字符串类型ChildName数量:', count); });改用JsStore的Where类构建条件
旧版本的JsStore对直接传入对象形式的Where条件可能存在类型处理bug,建议用官方推荐的Where类API来构建查询条件:import { Where } from 'jsstore'; GetArticleFromIndexedDb(section) { return this._connection.select({ From: this._indexedDBLiveDBTableName, Where: Where('ChildName').is(section) }); }
二、1.4.1版本的"Maximum call stack size exceeded"错误
这个栈溢出问题大概率是重复调用openDb导致的内部状态混乱,或者JsStore 1.4.1版本的已知bug。
排查与解决方案:
仅初始化一次数据库连接
你的代码中每次调用GetArticleFromIndexedDb都会执行this._connection.openDb,而openDb是异步操作,重复调用会导致JsStore内部递归处理连接状态,最终引发栈溢出。
应该将数据库初始化移到组件/服务的初始化逻辑中(比如Angular的ngOnInit),只调用一次:ngOnInit() { // 传入完整的schema对象,确保数据库结构正确 this._connection.openDb(this.getDbSchema()).then(() => { console.log('数据库连接成功'); }).catch(err => { console.error('数据库连接失败:', err); }); } GetArticleFromIndexedDb(section) { // 直接查询,无需重复打开数据库 return this._connection.select({ From: this._indexedDBLiveDBTableName, Where: Where('ChildName').is(section) }); }确保Connection实例是单例
检查你是否每次查询都创建了新的JsStore Connection实例。正确的做法是全局维护一个单例Connection,避免重复实例化导致的资源冲突和递归问题。升级到JsStore最新稳定版
1.4.1版本可能存在栈溢出的已知bug,建议升级到最新的1.4.x稳定版本,官方可能已经修复了该问题。
额外建议
- 始终确保存入的数据与你定义的Schema字段类型完全匹配,IndexedDB对类型一致性要求严格;
- 在查询前可以先判断数据库是否已经打开,避免重复调用
openDb:if (!this._connection.isDbOpen()) { // 仅在未打开时执行初始化 await this._connection.openDb(this.getDbSchema()); }
内容的提问来源于stack exchange,提问作者kamalav

