javascript - Node.js 事件循环忽略读取流数据事件中的 setTimeout?
问题描述
我正在澄清我对 Node.js 如何执行计时器的疑问。通常,当您的节点脚本中有一个 setTimeout 块时,事件循环,即使没有其他任何内容,也会在 setTimeout 中等待指定的毫秒数,并在运行回调后退出。
但考虑下面的代码
const fs = require('fs');
let readable = fs.createReadStream('large.csv');
readable.on('data', async chunk => {
let rows = parseCsvRow(chunk);
try {
for (let i = 0; i < rows.length; i++) {
console.log(i);
await someAsyncOperation(rows[i]);
}
} catch (error) {
//something went wrong
}
});
readable.on('end', chunk => {
console.log('csv file processed successfully');
});
function someAsyncOperation(){
return new Promise((resolve, reject) => {
setTimeout(resolve, 2000);
});
}
我正在阅读的 csv 文件有大约 300 行,我正在为每个(为简单起见隐藏代码)触发一个 ajax 请求,运行大约需要 100 毫秒,我在这里使用 setTimeout 对其进行了模拟。
当我运行上面的程序时,它几乎立即退出,而无需等待所有挂起的 setTimeout 计时器成功运行。仅仅因为从data
读取流上的事件内部安排的计时器会忽略它吗?它不应该等待所有计时器执行吗?
注意 - 我知道上面的代码不是做我正在做的事情的正确方法,但这只是一个示例,用于展示我很难理解的概念。
解决方案
这与 Node.js 或事件循环无关。
问题是你将一个async
函数传递给一个不会对它返回的承诺做任何事情的东西。这是承诺的反模式之一。仅async
当以下之一为真时,才将函数用作回调:
- 执行回调的事物将使用或返回承诺(例如,
Promise.all
因为它使用它们,或者map
在数组上因为它返回它们) - 您不在乎调用您的
async
函数的东西是否继续工作,而您的async
函数可能会暂停在 上await
,并且async
您将函数中的所有内容包装在处理拒绝的try
/中。catch
Node.js 的特定部分是:如果您想阻止对data
处理程序的进一步调用,直到您完成某些操作,您需要先调用pause
流,然后再调用resume
它。
推荐阅读
- html - tcpdf 没有显示正确的结果
- javascript - 如何使用 javascirpt 和 jquery 自定义格式日期
- networking - 为什么在后台运行 VPN 会影响 Yggdrasil IP 访问?
- node.js - 降级 Nodejs 和 Npm
- php - 无法在 Codeigniter 4 中捕获错误
- sql - 如果参数不为空,则有条件地添加到 WHERE 子句
- python - 删除接下来 n 行中的重复值,但保留第一个
- laravel - API 不支持会话。如何在 API 中使用会话?
- javascript - 为什么没有定义构造函数中的change(),它应该通过p.__proto__中的__proto__链接访问?
- python - 如何更改此循环以插入单词“CHANGE”