2016-03-30 3 views
1

Я читал 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() был проигнорирован. Это так? Может кто-то пролить свет?

ответ

1

Вы можете добавить некоторые заявления протоколирования, чтобы увидеть, что происходит:

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).

+0

ли я это правильно понял? В принципе, после вызова первого 'it.next()', 6 возвращается вызывающему, а узел приостанавливает функцию на том же выходе? Таким образом, при вызове 'it.next (12)' он использует 12 вместо x + 1, правильно? – Geo

+0

@Geo: Именно так работает 'yield', да :-) В большинстве случаев (например, итераторы) вам не нужны значения, которые передаются (или вообще не передаются значения), но вы можете сделать некоторые причудливые вещи с этим. Пойдите, прочитайте в серии статей, которые вы связали в своем вопросе! – Bergi

2

Это может помочь

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) 
} 
Смежные вопросы