2014-11-21 2 views
1

Я пытаюсь понять, как это работает. Я обработал этот код наизнанку и до сих пор не понимаю, как он возвращает значения. Я получил это из учебника по http://davidwalsh.name/es6-generatorsES6 Generator baffling me

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 } 

я, кажется, несколько обхвата на первый следующий(), но следующие 2 расстроить меня со значением 8 и 42.

Надежды кто-то может помочь объяснить это, поэтому я могу попытаться понять и перейти на следующие этапы с генераторами.

+0

Похоже, вы, по крайней мере, второй человек, чтобы быть сбит с толку этой конкретной обучающей программы. Возможно, настало время найти другую. –

+0

Да, это дубликат, но я до сих пор не думаю, что другой вопрос ответил полностью. В обоих ответах сказано, что первое значение равно 6, но фактическое начальное значение для самого результата - 5. Я думаю, что нужно понимать разницу между тем, что контекст выполнения до выхода приостанавливается, а затем, когда он всплывает контекст выполнения и возвращает оценка. Это неправильно? – pertrai1

+0

Я не понимаю ни одной части вашего комментария. Что вы подразумеваете под «фактическим начальным значением для самой доходности 5?»? –

ответ

2

Аргумент next становится значением предыдущего yield. Это поток:

it.next() запускает генератор. Его значение получается как x + 1, что составляет 6.

it.next(12) возобновляет генератор, возвращая 12 в качестве значения yield (x + 1). y будет 2 * 12, т.e. 24. Значение it.next(12) приведено как 24/3, то есть 8.

it.next(13) возобновляет генератор, возвращая 13 как значение yield (y/3), так 13 присваивается z. Таким образом, конечным результатом является 5 + 24 + 13, или 42.

TL; ДР:next возобновляет генератор и передает значение, возвращаемое yield. yield останавливает генератор и передает значение, возвращаемое next. Это как эта забавная игра в цифровой теннис.

+0

УДИВИТЕЛЬНЫЙ !!! Большое вам спасибо за то, что вы просто поняли, когда я сидел здесь, в консоли, пытаясь понять это. – pertrai1

5

Генераторы не более синтаксическими для закрытия, попробуйте следующее:

function foo(x) 
    { 
    var step = 0; 
    var y; 
    var z; 

    function next(p) { 

     switch(step++) { 
     case 0: return { done:false, value:x + 1 }; break; 
     case 1: y = 2 * p; return { done:false, value:y/3 }; break; 
     case 2: z = p; return { done:true, value: x + y + z }; break; 
     default: return; 
     } 
    } 
    return {next:next}; 
    }  

    var it = foo(5); 
    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 } 
+0

Ах! Спасибо за то, что поделился этим. Другой пример, который помог пролить свет на это для меня. Очень признателен. – pertrai1