超出最大 IPC 消息大小
Maximum IPC message size exceeded
目前,我正在网络浏览器上开发工具 运行。
在这个项目中,我使用 IndexedDB 和 Dexie.js 版本 2.x。
在 Google Chrome 上,我提到了错误 "Maximum IPC message size exceeded"。估计是IndexedDB里面放了这么大的数据造成的。
我的临时实现是通过JSON.stringify
将数组转换为字符串,我曾经实现过这个问题。然而,问题又出现了。
- 在我的应用程序中,定义了一个名为
Project
的聚合。
- 每个
Project
最多有500个Input text
。
- 每个
Input text
有1个字符串,最大长度为50k。
- 另外,每个
Project
有Analysis
,但它只包含分析参数。
- 每个
Analysis
有很多Result
。
- 每个
Result
包含长度为20k。
Input text
和 Result
通过 IndexedDB 的 getAll()
方法获取,通过 projectId
或 analysisId
. 过滤
我的问题是...
- 如何避免这个错误?
- 我想拯救存储在 IndexedDB 中的数据。我知道数据存储在本地文件系统中的什么位置。如果可以的话,怎么做?
如果您查看 Chrome 实现中导致此错误的原因,例如 https://chromium.googlesource.com/chromium/src.git/+/master/content/browser/indexed_db/indexed_db_database.cc,当消息大小过大时会发生此错误。这里的消息大小基本上是指作为某些处理的结果从 C++(浏览器二进制文件)发送到 Javascript 的数据量。
为避免发送过多数据,您可以执行以下操作:
- 确保您永远不会对大量数据调用 getAll
- 在对潜在大量数据调用 getAll 时使用限制
- 使用 openCursor 而不是 getAll
- 存储较小的对象
我认为最好的办法是尝试切换到 openCursor。这将一次取回您的物品(根据请求)。这样你就可以避免 运行 进入这个错误。使用游标会稍微降低速度,但会获得可伸缩性。
要像 getAll 一样使用游标,很简单。您需要做的就是首先声明一个空数组,然后启动游标,并迭代,每次将游标项添加到数组中。在迭代结束时,您基本上一次从一个片段中组装出与调用 getAll 相同的数组结果。
如果你在一些大数据集上使用Dexie的toArray()
方法,尝试用offset(number)
和limit(number)
限制记录数,以批量获取数据
我找不到类似游标的方式来使用 Dexie 进行查询(可能看起来不够难),但我想继续使用 Dexie 作为我的抽象层。
我需要检索所有记录并根据 ID 检索一个子集(与您相同),我想到了以下解决了我们的问题:
/**
* Retrieve all of Dexie collection
*
* We can't just call Collection.toArray() because once the result is large
* enough, we'll get "Maximum IPC message size exceeded" error. This is a
* memory-friendly implementation. Although maybe a bit slow due to a page
* size of one.
*/
function retrieveDexieCollection(collection) {
return new Promise(async (resolve, reject) => {
try {
const result = []
await collection.each(r => {
result.push(r)
})
return resolve(result)
} catch (err) {
return reject(err)
}
})
}
// then later, use our function
const projectIds = [1,2,3]
const records = await retrieveDexieCollection(db
.whateverYourTableIsCalled
.where('projectId')
.anyOf(projectIds))
如果您需要随时处理记录(我就是这样做的),您可以添加一个 mappingFunction
参数并在将每个元素添加到数组之前调用它。
该函数非常灵活,因为您可以将任何 Dexie 集合传递给它;整个 table 或任意查询的结果。
目前,我正在网络浏览器上开发工具 运行。
在这个项目中,我使用 IndexedDB 和 Dexie.js 版本 2.x。
在 Google Chrome 上,我提到了错误 "Maximum IPC message size exceeded"。估计是IndexedDB里面放了这么大的数据造成的。
我的临时实现是通过JSON.stringify
将数组转换为字符串,我曾经实现过这个问题。然而,问题又出现了。
- 在我的应用程序中,定义了一个名为
Project
的聚合。 - 每个
Project
最多有500个Input text
。 - 每个
Input text
有1个字符串,最大长度为50k。 - 另外,每个
Project
有Analysis
,但它只包含分析参数。 - 每个
Analysis
有很多Result
。 - 每个
Result
包含长度为20k。 Input text
和Result
通过 IndexedDB 的getAll()
方法获取,通过projectId
或analysisId
. 过滤
我的问题是...
- 如何避免这个错误?
- 我想拯救存储在 IndexedDB 中的数据。我知道数据存储在本地文件系统中的什么位置。如果可以的话,怎么做?
如果您查看 Chrome 实现中导致此错误的原因,例如 https://chromium.googlesource.com/chromium/src.git/+/master/content/browser/indexed_db/indexed_db_database.cc,当消息大小过大时会发生此错误。这里的消息大小基本上是指作为某些处理的结果从 C++(浏览器二进制文件)发送到 Javascript 的数据量。
为避免发送过多数据,您可以执行以下操作:
- 确保您永远不会对大量数据调用 getAll
- 在对潜在大量数据调用 getAll 时使用限制
- 使用 openCursor 而不是 getAll
- 存储较小的对象
我认为最好的办法是尝试切换到 openCursor。这将一次取回您的物品(根据请求)。这样你就可以避免 运行 进入这个错误。使用游标会稍微降低速度,但会获得可伸缩性。
要像 getAll 一样使用游标,很简单。您需要做的就是首先声明一个空数组,然后启动游标,并迭代,每次将游标项添加到数组中。在迭代结束时,您基本上一次从一个片段中组装出与调用 getAll 相同的数组结果。
如果你在一些大数据集上使用Dexie的toArray()
方法,尝试用offset(number)
和limit(number)
限制记录数,以批量获取数据
我找不到类似游标的方式来使用 Dexie 进行查询(可能看起来不够难),但我想继续使用 Dexie 作为我的抽象层。
我需要检索所有记录并根据 ID 检索一个子集(与您相同),我想到了以下解决了我们的问题:
/**
* Retrieve all of Dexie collection
*
* We can't just call Collection.toArray() because once the result is large
* enough, we'll get "Maximum IPC message size exceeded" error. This is a
* memory-friendly implementation. Although maybe a bit slow due to a page
* size of one.
*/
function retrieveDexieCollection(collection) {
return new Promise(async (resolve, reject) => {
try {
const result = []
await collection.each(r => {
result.push(r)
})
return resolve(result)
} catch (err) {
return reject(err)
}
})
}
// then later, use our function
const projectIds = [1,2,3]
const records = await retrieveDexieCollection(db
.whateverYourTableIsCalled
.where('projectId')
.anyOf(projectIds))
如果您需要随时处理记录(我就是这样做的),您可以添加一个 mappingFunction
参数并在将每个元素添加到数组之前调用它。
该函数非常灵活,因为您可以将任何 Dexie 集合传递给它;整个 table 或任意查询的结果。