问题描述
我已经阅读了几个使用JavaScript生成器的代码示例。我能想出的最简单的生成器使用块是这样的:
I've read over several examples of code using JavaScript generators such as this one. The simplest generator-using block I can come up with is something like:
function read(path) {
return function (done) {
fs.readFile(path, "file", done);
}
}
co(function *() {
console.log( yield read("file") );
})();
这确实打印出文件的内容
,但我的挂断是调用完成
的地方。看起来,yield是一个语法糖,用于包装它在回调中返回的内容并适当地分配结果值(至少在 co 的情况下,将error参数抛给打回来)。我对语法的理解是否正确?
This does indeed print out the contents of file
, but my hangup is where done
is called. 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). Is my understanding of the syntax correct?
完成
什么看起来像 yield
被使用了吗?
What does done
look like when yield
is used?
推荐答案
不,收益率
不是语法糖。它是生成器的核心语法元素。当实例化该生成器时,您可以运行它(通过调用 .next()
),这将返回返回值
ed或 yield
ed。当生成器 yield
ed时,您可以稍后再次调用 .next()
继续它。 next
的参数将是 yield
expresion在生成器内返回的值。
No, yield
is no syntactic sugar. It's the core syntax element of generators. When that generator is instantiated, you can run it (by calling .next()
on it), and that will return the value that was return
ed or yield
ed. When the generator was yield
ed, you can continue it later by calling .next()
again. The arguments to next
will be the value that the yield
expresion returns inside the generator.
在 co 的情况下只有
,那些异步回调的东西(以及)适当处理异步控制流库中您认为自然的内容。
Only in case of co
, those async callback things (and other things) are handled "appropriately" for what you would consider natural in an async control flow library.
thread
来自的功能示例为您提供了这样的好印象:
The thread
function example from the article that you read gives you a good impression of this:
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
表达式返回了此值。
In your code, yield
does yield the value of the expression read("file")
from the generator when it is ran. This becomes the ret.val
, the result of gen.next()
. To this, the next
function is passed - a callback that will continue the generator with the res
ult that was passed to it. In your generator code, it looks as if the yield
expression returned this value.
展开版本发生的事情可以这样写:
An "unrolled" version of what happens could be written like this:
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
});
这篇关于了解产量/生成器的代码流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!