首先我经常使用 async 和 await 并且我得到这个错误:
RangeError: Value undefined out of range for undefined options property undefined
at Set.add (<anonymous>)
at AsyncHook.init (internal/inspector_async_hook.js:19:25)
at PromiseWrap.emitInitNative (internal/async_hooks.js:134:43)
而且我不知道如何解决这个问题,我完全用 Typescript 编写我的代码并且我没有创建任何名为“async_hooks”的文件。
而且我不会一次运行超过 10 个异步函数,我经常使用 await,所以它不应该堆积,但 javascript 似乎不会减少 asyncId 并很快达到数量限制。
我尝试使用 less async await 但这并没有解决问题,但错误消息稍后出现。如果我使用非常少的 async await 我可以防止这个错误出现,直到函数成功完成工作。 (我用的是 Electron 7)
Electron 似乎有一个非常低的异步池,但它可以通过默认的打字稿代码复制:
class Test {
private async testCompare(a,b):Promise<boolean> {
return a == b;
}
public async testRun():Promise<void> {
for (let index = 0; index < 999999999; index++) {
for (let index2 = 0; index2 < 999999999; index2++) {
await this.testCompare(index,index2)
}
}
}
}
new Test().testRun();
这段代码产生了非常多的 ram 使用,我想我的程序中也有同样的问题。我认为异步池会被填满直到达到极限。
当我的设置大小达到 16777216 (2^24) 时,我对
Set.add
遇到了与您相同的错误。我无法在文档中找到有关此限制的信息,但我假设集合限制为 16777216 个唯一值?
使用简单的 for 循环轻松测试。
这将引发完全相同的错误:
let s = new Set();
for (let i = 0; i <= 16777216; i++) s.add(i);
这将成功运行:
let s = new Set();
for (let i = 0; i < 16777216; i++) s.add(i);
请注意,这会占用约 5GB 的内存,因此如果由于内存限制而崩溃,请相应地增加堆限制。
刚刚使用 Set 遇到这个问题,我使用以下方法作为快速解决方法
class Set {
hash = {}
add (v) {
this.hash[JSON.stringify(v)] = true
}
has (v) {
return this.hash[JSON.stringify(v)] == true
}
}
这没有限制,仅受您的系统内存限制
解决方法(和
Set
一样快)和Unique,
const setA = {};
try {
for (let i = 0; i < 16777216 + 500; i++) setA[i] = null;
} catch (err) {
console.log('Died at ', setA.size, ' Because of ');
console.error(err);
}
console.log('lived even after ', Object.keys(setA).length);
RangeError: Value undefined out of range for undefined options property undefined
上面的错误是当一个Set达到元素的最大限制时引起的。 请参阅参考资料:Node.js Map 中的最大条目数?
large-set
,一个允许您存储和处理大量元素的包,而不必担心 Set by partitions into 中的 16.777.216 (2^24) 限制当它达到限制时更小的集合,使其能够存储和访问比内置集合更多的元素。
但是如果你不想使用任何包,你可以尝试这个小的解决方法:
class LargeSet {
constructor(limit = 16777216) {
this.limit = limit;
this.sets = [new Set()];
}
has(value) {
return this.sets.some(set => set.has(value));
}
add(value) {
if (this.sets[this.sets.length - 1].size >= this.limit) {
this.sets.push(new Set());
}
if (this.has(value)) return this;
this.sets[this.sets.length - 1].add(value);
return this;
}
delete(value) {
for (const set of this.sets) {
if (set.delete(value)) return true;
}
return false;
}
clear() {
this.sets = [new Set()];
}
}
然后测试代码:
const largeSet = new LargeSet();
for (let i = 0; i <= 16777216; i++) {
largeSet.add(i); // No errors will be thrown
}
const set = new Set();
for (let i = 0; i <= 16777216; i++) {
set.add(i); // Throws a 'RangeError: Value undefined out of range for undefined options property undefined'
}