2016-07-22 4 views
3

начать обучение генератора, я столкнулся со следующим сценарием.es6 Генератор в то время как (true)

Я смущен первым next(), почему console.log не печатается для самого первого следующего().

function* callee() { 
    console.log('callee: ' + (yield)); 
} 
function* caller() { 
    while (true) { 
     yield* callee(); 
    } 
} 

> let callerObj = caller(); 

> callerObj.next() // start 
{ value: undefined, done: false } 
// why console.log is not returning 'callee' ?? 

> callerObj.next('a') 
callee: a 
{ value: undefined, done: false } 

> callerObj.next('b') 
callee: b 
{ value: undefined, done: false } 
+0

кто бы ни покидал этот минус, оставьте свой разум! Я спрашиваю что-то, с чем я смущен. – Bruce

+1

Эта статья помогла мне понять генераторы и некоторые из их практических приложений. https://davidwalsh.name/es6-генераторы – jusopi

ответ

4

Если у вас есть генератор это стартов в подвешенной фазе и первый next вызова запускает генератор до предела текучести первого. Когда вы «выходите из» подгенератора, каждый раз. Если добавить протоколирование в точках входа обеих ваших функций вы увидите следующее:

function* callee() { 
    console.log('Callee is running up to the first yield point'); 
    console.log('callee: ' + (yield)); 
} 
function* caller() { 
    console.log('Caller is running up to the first yield point'); 
    while (true) { 
    yield* callee(); 
    } 
} 

При запуске этой реализации, используя тестовый код, который вы увидите:

> let t = caller() 
> t.next() 
Caller is running up to the first yield point 
Callee is running up to the first yield point 
Object {value: undefined, done: false} 
+0

что вы имеете в виду первый предел? – Bruce

+1

спасибо за ответ update – Bruce

+0

Я предполагаю, что первая пауза - это выход * callee(); или console.log ('callee:' + (yield)); ? – Bruce

3

При запуске генератора (callerObj.next()), он всегда поднимается до первого yield. Поскольку делегирование (yield *) к другому генератору, что выход будет один в callee:

function* callee() { 
    console.log('callee: ' + (yield)); 
       // this yield ^^^^^ 
} 

Здесь генератор останавливается до того выполнения console.log. Если бы вы были yield значение назад, это было бы возвращение value вашего первого callerObj.next() вызова:

function* callee() { 
    console.log('callee: ' + (yield 'value')); 
} 

Следующая callerObj.next('a') вызов будет заменить значение на yield с 'a' и вызвать console.log. В псевдокоде:

console.log('callee: ' + 'a'); 
// `yield` is replaced with 'a' for this invocation 

Он будет работать до тех пор, пока не встретит ту же yield снова (так как вы находитесь в бесконечном цикле).

+0

спасибо nil хорошо объяснено :) – Bruce

+1

'yield' в основном =« приостановить »в терминах выполнения кода, где« generatorObj.next (.. .) '=" play ". Это, по крайней мере, то, как я концептуализую это. – jusopi

+0

Я предполагаю, что первая пауза - это выход * callee(); или console.log ('callee:' + (yield)); ? – Bruce

Смежные вопросы