Node js 事件循环:安全 for 循环和 Python 区别
Node js event loop: Safe for-looping and Python difference
在为我的 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 操作。
首先,测量您现有代码的性能:它可能不是瓶颈。
如果假设的瓶颈实际上是有效的,您可以创建一个异步 Node C++ add-on,它可以通过 uv_queue_work()
在单独的线程中处理整个 JSON blob,在 JavaScript 事件循环,然后 return 使用 promise 将整个结果返回 JavaScript。
这个受支持的性能瓶颈是否足以引起关注以保证这样做?应该不是。
关于您的 console.log() 问题:在 Node 中,有时 stdio 是同步的,有时不是:参见 this discussion。如果您在 POSIX 系统上,它是同步的,并且您正在写入足够的数据来填满管道并阻塞事件循环,在下一个事件滴答之前,所有这些都被卡在那里。我不确定导致崩溃的具体原因,但希望这是回答您问题的开始。
在为我的 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 操作。
首先,测量您现有代码的性能:它可能不是瓶颈。
如果假设的瓶颈实际上是有效的,您可以创建一个异步 Node C++ add-on,它可以通过 uv_queue_work()
在单独的线程中处理整个 JSON blob,在 JavaScript 事件循环,然后 return 使用 promise 将整个结果返回 JavaScript。
这个受支持的性能瓶颈是否足以引起关注以保证这样做?应该不是。
关于您的 console.log() 问题:在 Node 中,有时 stdio 是同步的,有时不是:参见 this discussion。如果您在 POSIX 系统上,它是同步的,并且您正在写入足够的数据来填满管道并阻塞事件循环,在下一个事件滴答之前,所有这些都被卡在那里。我不确定导致崩溃的具体原因,但希望这是回答您问题的开始。