我已经阅读了几个使用 JavaScript 生成器的代码示例 such as this one .我能想出的最简单的使用生成器的 block 是这样的:
function read(path) {
return function (done) {
fs.readFile(path, "file", done);
}
}
co(function *() {
console.log( yield read("file") );
})();
这确实打印出了 file
的内容,但我的挂断是在调用 done
的地方。看起来,yield 是一种语法糖,用于将它返回的内容包装在回调中并适本地分配结果值(至少在 co
的情况下,将错误参数抛给回调)。我对语法的理解是否正确?
当使用 yield
时,done
是什么样子的?
最佳答案
Seemingly, yield is syntactic sugar for wrapping what it returns to in a callback and assigning the result value appropriately (and at least in the case of co, throwing the error argument to the callback)
不,yield
不是语法糖。它是生成器的核心语法元素。当该生成器被实例化时,您可以运行它(通过对其调用 .next()
),这将返回 return
ed 或 yield 的值
编辑。当生成器 yield
时,您可以稍后通过再次调用 .next()
继续它。 next
的参数将是 yield
表达式在生成器中返回的值。
只有在 co
的情况下,那些异步回调事物(和 other things )被“适本地”处理为您认为在异步控制流库中自然发生的事情.
What does done look like when yield is used?
article that you read 中的thread
函数示例给你一个好印象:
function thread(fn) {
var gen = fn();
function next(err, res) {
var ret = gen.next(res);
if (ret.done) return;
ret.value(next);
}
next();
}
在您的代码中,yield
确实在生成器运行时从生成器中生成表达式 read("file")
的值。这成为 ret.val
,gen.next()
的结果。为此,传递了 next
函数 - 一个回调函数,它将使用传递给它的 result
ult 继续生成器。在您的生成器代码中,看起来好像 yield
表达式返回了这个值。
发生的事情的“展开”版本可以这样写:
function fn*() {
console.log( yield function (done) {
fs.readFile("filepath", "file", done);
} );
}
var gen = fn();
var ret1 = gen.next();
var callasync = ret1.value;
callasync(function next(err, res) {
var ret2 = gen.next(res); // this now does log the value
ret2.done; // true now
});
关于javascript - 使用 yield/generators 理解代码流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23551418/