![](/img/trans.png)
[英]Understanding Async Control Flow with Promises, Generators and Async/Await
[英]Understanding code flow with yield/generators
我已经阅读了使用JavaScript生成器( 例如this)的几个代码示例。 我可以想到的最简单的生成器使用块是:
function read(path) {
return function (done) {
fs.readFile(path, "file", done);
}
}
co(function *() {
console.log( yield read("file") );
})();
确实确实打印出了file
的内容,但是我的挂断称为done
。 貌似,yield是语法糖,用于将其返回的内容包装在回调中并适当地分配结果值(至少在co
的情况下,将error参数抛出给回调)。 我对语法的理解正确吗?
使用yield
done
看起来像什么?
看起来,yield是语法糖,用于将其返回的内容包装在回调中并适当地分配结果值(至少在使用co的情况下,将error参数抛出给回调)
不, yield
不是语法糖。 这是生成器的核心语法元素。 实例化该生成器后,可以运行它(通过在其上调用.next()
),它将返回return
ed或yield
ed的值。 当发电机是yield
版,您可以在以后通过调用继续它.next()
一次。 next
的参数将是yield
表达式在生成器内部返回的值。
仅在使用co
情况下, 才按照您认为在异步控制流库中自然的方式“适当地”处理那些异步回调事物(和其他事物 )。
使用收益率后,看起来像什么?
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
});
我在这里发布了有关发电机如何工作的详细说明。
以简化形式,您的代码可能看起来像这样,不带co
(未经测试):
function workAsync(fileName)
{
// async logic
var worker = (function* () {
function read(path) {
return function (done) {
fs.readFile(path, "file", done);
}
}
console.log(yield read(fileName));
})();
// driver
function nextStep(err, result) {
try {
var item = err?
worker.throw(err):
worker.next(result);
if (item.done)
return;
item.value(nextStep);
}
catch(ex) {
console.log(ex.message);
return;
}
}
// first step
nextStep();
}
workAsync("file");
workAsync
的驱动程序部分通过调用nextStep()
异步迭代生成器对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.