我正试图了解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
始终会返回{}
而不是文件内容。
希望我想要实现的目标仍然是可能的,或者我可能完全错过了发电机/产量的点,我完全错误地使用它,在这种情况下指出我出错的地方和任何资源都会太棒了。
答案 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);
});
上阅读本文,详细了解这种死亡的简单模式(并在线试用)
答案 1 :(得分:2)
只是有点消解和更新(似乎raise
已重命名为throw
)lgersman'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.readdir
和fs.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'));