我试图了解如何在 fast-csv 中使用 Fiber 来制作逐行阅读器(单用户命令行脚本),该阅读器在每一行暂停读取/处理,直到该行完成各种异步调用. (不滚动我自己的 csv 代码,我想使用一些已经弄清楚关于 csv 格式的问题的东西)
如果我这样做
var csv = require("fast-csv");
var CSV_STRING = 'a,b\n' +
'a1,b1\n' +
'a2,b2\n';
csv
.fromString(CSV_STRING, {headers: false})
.on("record", function (data) {
console.log("line="+JSON.stringify(data));
setTimeout(function(){
console.log("timeout");
},2000);
})
.on("end", function () {
console.log("done parsing CSV records");
});
console.log("done initializing csv parse");
我得到了我的期望:
done initializing csv parse
line=["a","b"]
line=["a1","b1"]
line=["a2","b2"]
done parsing CSV records
timeout
timeout
timeout
如果我尝试在每条记录后使用 Fiber
Fiber(
function () {
var fiber = Fiber.current;
csv
.fromString(CSV_STRING, {headers: false})
.on("record", function (data) {
console.log("line="+JSON.stringify(data));
setTimeout(function(){
console.log("timeout");
fiber.run();
},2000);
Fiber.yield();
})
.on("end", function () {
console.log("done parsing CSV records");
});
console.log("done initializing csv parse");
}).run();
我明白了
done initializing csv parse
line=["a","b"]
events.js:141
throw er; // Unhandled 'error' event
^
Error: yield() called with no fiber running
我想我明白发生了什么,Fiber().run() 中的代码完成了,所以它在调用 yield 之前离开了 Fiber,所以当它达到 yield 时不再有 Fiber。(因此聪明的错误消息“没有光纤运行”)
在我完成解析之前,让我保持光纤运行的合适方法是什么?
似乎是一个简单的问题,但我没有看到明显的答案?起初,我想在它离开 Future().run() 之前设置一个 yield,但这不起作用,因为第一个 fiber.run() 会让它再次离开 Fiber。
我想要的是流程是这样的:
done initializing csv parse
line=["a","b"]
timeout
line=["a1","b1"]
timeout
line=["a2","b2"]
timeout
done parsing CSV records
但如果不重新处理 fast-csv 的内部,这可能是不可能的,因为它控制了每个记录何时触发事件。我目前的想法是,必须让每个事件在 fast-csv 中被触发,并让处理 csv.on("record") 中的事件的用户将控制权交还给快速解析 csv 的循环-csv。