在发生器/产量中包装fs.readFile

我试图让我的头在发电机和JavaScript和Node.js屈服,但有一个问题。

理想情况下,我想要做的就是将fs.readFile与generate / yield包装起来,这样我就可以同步使用它而不会阻塞任何东西。

我已经拿出了下面的代码:

function readFileSync (path) { return (function *(){ return yield require('fs').readFile(path, function *(err, data){ yield data; }); })(); } console.log(readFileSync('test-file.txt')); 

但是,不幸的是, readFileSync总是返回{}而不是文件内容。

希望我想达到的目标仍然是可能的,或者我完全错过了发生器/产量的观点,而且我完全错误地使用它,在这种情况下,指出我出错的地方,任何资源都会很好。

如何使用节点启用和声function( node --harmony )和这个超级简单的ES6代码片段:

 function run( gen, iter) { (iter=gen( (err, data) => (err && iter.raise(err)) || iter.next(data))).next(); } run(function* (resume) { var contents = yield require('fs').readFile(path, resume); console.log(contents); }); 

你可以在这篇文章的orangevolt.blogspot.com上阅读更多关于这个死的简单模式(并在线试用)

你可以使用像Wait.for-ES6这样的助手库(我是作者)

临的 :你可以顺序调用任何标准的asynchronousnode.jsfunction

Con's :你只能在一个生成器function*里面做function*

使用fs.readdirfs.readfile (都是标准的asynchronousnode.js函数

 var wait=require('wait.for-es6'), fs=require('fs'); function* sequentialTask(){ var list = yield wait.for(fs.readdir,'/home/lucio'); console.log(list); // An array of files var data = yield wait.for(fs.readFile,list[0]); //read first file console.log(data); // contents } wait.launchFiber(sequentialTask); 

只是有点desugerifying和更新(似乎raise更名throw ) lgersman的答案,使其与io.js 1.0.4工作:

 function run(gen) { var iter = gen(function (err, data) { if (err) { iter.throw(err); } return iter.next(data); }); iter.next(); } run(function* (resume) { var contents = yield require('fs').readFile(path, resume); console.log(contents); }); 

谢谢lgersman!

将一个asynchronous函数变成一个具有生成器的同步函数是不可能的。

发电机可以自行中断,但不能中断其他function的控制stream。

所以你的代码如何工作的唯一方法是如果它在另一个生成器中:

 console.log(yield* readFileSync('test-file.txt'));