似乎,yield 是一种语法糖,用于将它返回的内容包装在回调中并适当地分配结果值(至少在 co 的情况下,将错误参数扔给回调)
不,yield不是语法糖。它是生成器的核心语法元素。当该生成器被实例化时,您可以运行它(通过调用.next()它),这将返回returned 或yielded的值。当生成器被yielded 时,你可以稍后通过.next()再次调用来继续它。的参数next将是yield表达式在生成器内返回的值。
只有在这种情况下co,那些异步回调事物(和其他事物)才会“适当地”处理您认为在异步控制流库中很自然的事情。
使用 yield 时 done 是什么样的?
您阅读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函数被传递 - 一个回调,它将使用res传递给它的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
});