我正在尝试将纤维与流一起使用:
var Fiber = require('fibers');
var Future = require('fibers/future');
var fs = require('fs');
function sleepForMs(ms) {
var fiber = Fiber.current;
setTimeout(function() {
fiber.run();
}, ms);
Fiber.yield();
}
function catchError(f, onError) {
return function () {
var args = arguments;
var run = function () {
try {
var ret = f.apply(null, args);
}
catch (e) {
onError(e);
}
return ret;
};
if (Fiber.current) {
return run();
}
else {
return Fiber(run).run();
}
}
}
function processFile(callback) {
var count, finished, onData, onException, onIgnoredEntry;
count = 0;
finished = false;
onException = function (error) {
if (finished) {
console.error("Exception thrown after already finished:", error.stack || error);
}
if (finished) {
return;
}
finished = true;
return callback(error);
};
onData = function(data) {
console.log("onData");
if (finished) {
return;
}
console.log("before sleep");
sleepForMs(500);
console.log("after sleep");
throw new Error("test");
};
return fs.createReadStream('test.js').on('data', catchError(onData, onException)).on('end', function() {
console.log("end");
if (finished) {
return;
}
finished = true;
return callback(null, count);
}).on('error', function(error) {
console.log("error", error);
if (finished) {
return;
}
finished = true;
return callback(error);
});
};
Fiber(function () {
console.log("Calling processFile");
Future.wrap(processFile)().wait();
console.log("processFile returned");
}).run();
console.log("back in main");
但它并没有真正起作用。数据回调在回调内部的光纤完成之前完成。所以上面的代码输出:
Calling processFile
back in main
onData
before sleep
end
processFile returned
after sleep
Exception thrown after already finished: Error: test
事实上,它应该更像是:
Calling processFile
back in main
onData
before sleep
after sleep
end
processFile returned
Error: test