在为Express应用程序项目时,我编写了一个递归方法,该方法从某个嵌套的JSON对象检索数据。大致来说,该方法如下所示:
# The depth of the fields is up to 3-4 levels, so no stack overflow danger.
_recursiveFindFieldName: function(someJSONStruct, nestedFieldList) {
if (nestedFieldList.length === 0) {
return someJSONStruct;
}
fields = someJSONStruct['fields'];
for (var i=0; i < fields.length; i++) {
subField = fields[i];
if (subField['fieldName'] === nestedFieldList[0]) {
return this._recursiveFindFieldName(subField, nestedFieldList.splice(1));
}
}
return null;
现在,通过声明,将此方法称为我的回调之一
data = _recursiveFindFieldName(someJSON, fieldPathList);
。但是,一位查看我的代码的朋友指出,此方法在潜在的大型JSON结构上是递归和迭代的,可能会阻止事件循环并阻止Express服务其他请求。
虽然确实有道理,但我不确定我是否应该担心CPU同步任务(而不是I / O)。至少从直观上看,它看起来并不简单。
我尝试使用此source来更好地了解事件循环的工作原理,并且很惊讶地看到以下代码使我的本地节点REPL崩溃。
for (var i = 0; i < 10000000; i++) {
console.log('hi:', i);
}
相对于Python(它也运行单线程,并轻松处理打印任务),我不确定是为什么会发生这种情况,以及它是否与我的情况有关(不涉及I / O)操作。
答案 0 :(得分:1)
首先,衡量现有代码的性能:开始时可能不是瓶颈。
如果假定的瓶颈实际上是有效的,则可以创建一个异步Node C++ add-on,该异步this discussion可以通过uv_queue_work()
在JavaScript事件循环之外的单独线程中处理整个JSON blob,然后返回整个结果通过使用承诺返回到JavaScript。
这个支持的性能瓶颈是否足以引起人们的关注?可能不是。
关于console.log()问题:在Node中,有时stdio是同步的,有时却不是:请参见{{3}}。如果您使用的是POSIX系统,则它是同步的,并且您正在写入足够的数据来填充管道并阻塞事件循环,在下一个事件滴答之前,所有事件循环都被卡在其中。我不确定导致崩溃的具体原因,但希望这是回答您的问题的开始。