为什么这个迭代器返回以下值?

时间:2016-03-30 17:16:59

标签: javascript ecmascript-6 generator

我正在阅读this article about javascript generators,我到达了以下代码段:

function *foo(x) {
    var y = 2 * (yield (x + 1));
    var z = yield (y / 3);
    return (x + y + z);
}

var it = foo( 5 );

// note: not sending anything into `next()` here
console.log( it.next() );       // { value:6, done:false }
console.log( it.next( 12 ) );   // { value:8, done:false }
console.log( it.next( 13 ) );   // { value:42, done:true }

我不明白第一个it.next()的目的。在执行它之后,这一行不应该在var z = yield (y / 3)暂停迭代器,y的值为6?不应该it.next(12)yield (y / 3)提供参数,z之后是4吗?我不明白为什么函数的结果不是5 + 12 + 4.这就好像忽略了第一个it.next()。是这样的吗?有人可以解释一下吗?

2 个答案:

答案 0 :(得分:3)

这可能会有所帮助

function *foo(x) {
    var y = 2 * (yield (x + 1)); 
       // x = 5 (from foo(5) ) so it yields 6
       // next(12) => var y = 2 * (12) == 24
    var z = yield (y / 3);
       // from above y = 24 so yields 8
       // next(13) => var z = 13    
    return (x + y + z);
       // 5 + 24 + 13 == 42 (and done: true)
}

答案 1 :(得分:2)

您可能需要添加一些日志记录语句以查看正在发生的事情:

function *foo(x) {
    console.log("starting");
    var y = 2 * (yield (x + 1));
    console.log("y", y);
    var z = yield (y / 3);
    console.log("z", z);
    return (x + y + z);
}

var it = foo( 5 );
console.log("it", it);
console.log(it.next());
console.log(it.next(12));
console.log(it.next(13));

日志

it {next: …}
starting
{ value:6, done:false }
y 24
{ value:8, done:false }
z 13
{ value:42, done:true }

如您所见,调用foo(5)仅创建生成器对象,但尚未启动它。只有第一次调用it.next()才能执行此操作,并返回第一个yield的结果。第一次调用不接受任何参数,因为它无论如何都无法在生成器函数内访问。

只有第二次调用.next(12),这里传入一个值,然后将恢复生成器代码,传入的值是yield表达式的结果(然后乘以2)。