在生成器/ yield中包装fs.readFile

时间:2014-02-19 20:59:24

标签: javascript node.js generator yield

我正试图了解JavaScript和Node.js中的生成器和产量,但是遇到了问题。

理想情况下,我想要做的是使用generators / yield包装fs.readFile,这样我就可以同步使用它而不会阻塞任何内容。

我想出了以下代码:

function readFileSync (path) {
    return (function *(){
        return yield require('fs').readFile(path, function *(err, data){
            yield data;
        });
    })();
}

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

但遗憾的是,readFileSync始终会返回{}而不是文件内容。

希望我想要实现的目标仍然是可能的,或者我可能完全错过了发电机/产量的点,我完全错误地使用它,在这种情况下指出我出错的地方和任何资源都会太棒了。

4 个答案:

答案 0 :(得分:10)

如何使用启用了和声功能的节点(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

上阅读本文,详细了解这种死亡的简单模式(并在线试用)

答案 1 :(得分:2)

只是有点消解和更新(似乎raise已重命名为throwlgersman's回答使其与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!

答案 2 :(得分:1)

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

Pro :您可以按顺序调用任何标准的async node.js函数

Con's :您只能在生成器function*

内执行此操作

使用fs.readdirfs.readfile的示例(两者都是标准async node.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);

答案 3 :(得分:-3)

不可能将异步函数转换为带生成器的同步函数。

发电机可以自行中断,但不能中断其他功能的控制流程。

因此,代码如何工作的唯一方法是它是否在另一个生成器中:

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