我们有一些不好的json,我们试图解析。不幸的是,它不是有效的json,因为它在有效载荷中返回未引号的NaN
。
我们正在从长期弃用的request
库切换到axios
库。这似乎使我们当前固定此有效负载的方法的内存使用量增加了一倍,但是我们的环境是内存受限的。文件是19MB,我们的约束是50MB。我认为与正则表达式的/解析有关的东西是在内存中复制json,除了axios
试图做的解析之外。
我们在axios周围使用包装器,因此直接与它交互是有限的。我必须重新实现部分包装器才能访问它,它是一个外部内部库。
我知道我们要保留的键,所以丢弃结构的其余部分而不是处理NaN实际上是更可取的。
我们想要的结构,看起来像DataUsages[]
export interface DataUsages {
dataUsageId: string;
dataUsageName: string;
}
我们得到的结构在数组中的对象中有额外的项,我们根本不关心"dataUsageDownstreamUsages"
,这个键可以而且正在被丢弃'
[
{
"dataUsageId": "42",
"dataUsageName": "myname",
"dataUsageDownstreamUsages": [NaN]
}
]
目前这是我们当前的方法
const reg1 = /[NaN]|NaN/gm
const parsed: EDMDataUsages[] = JSON.parse(
requireNonNullish(response.body, 'body').replace(reg1, '""').replace(/NAN/gm, ''),
)
stream-json
现在我正在考虑使用stream-json
。
如果我使用解析器,它会退出,大概当它达到NaN
时。所以我在看disassembler
,但我不明白如何做到这一点。
const read = new Readable()
read.push(requireNonNullish(response.body, 'body'))
read.push(null)
const pipeline = chain([read, disassembler(), pick({ filter: 'data' }), data => this.log.trace('data', data)])
pipeline.on('data', data => this.log.trace('filter', data))
显然这段代码是不完整的
其他库也是可以接受的。请提供一个完整的例子。
好的,首先让我们创建一个伪数据
function genreateFakeData() {
const payload = { res: [] }
const mock = {
"dataUsageId": "42",
"dataUsageName": "myname",
"dataUsageDownstreamUsages": [NaN]
}
let totalFileSize = 0;
const fileSize = 19;
const SIZE_IN_BYTES = JSON.stringify(mock).length;
const SIZE_IN_MB = SIZE_IN_BYTES / 1024 / 1024;
while (totalFileSize < fileSize) {
totalFileSize += SIZE_IN_MB;
payload.res.push(mock);
}
fs.appendFileSync('fake.json', JSON.stringify(payload));
}
然后测试文件的大小是否正确
> ls -ltrh | grep fake
-rw-r--r-- 1 naor.tedgi staff 19M Jun 15 09:34 fake.json
让我们在堆约束下运行node应用程序并改变原始响应
node --max-old-space-size=50 index.js
index.js
const stream = require('stream');
const fs = require('fs');
const data = JSON.parse(fs.readFileSync('fake.json',{encoding:'utf8', flag:'r'}));
data.res.forEach(entry=>{
delete entry.dataUsageDownstreamUsages
})
console.log(data)