Первый it.next()
соответствует yield(x + 1)
, что, как и ожидалось, дает 6. 12 в следующем вызове it.next(12)
устанавливает значение этого первого выхода равным 12, поэтому y
удваивается, или 24, а итератор возвращает значение (y / 3)
, равное 8. Последний вызов it.next(13)
устанавливает значение второй дает значение 13, для которого установлено значение z
, и получает значение return
, равное 5 + 24 + 13.
Конечно, это немного сбивает с толку из-за синтаксиса
z = yield(y / 3)
что каким-то образом выглядит так, как будто кто-то присваивает значение чего-то, связанного с y / 3
, z
. Это не так. y / 3
– это значение, которое передается в качестве значения итератора, тогда как z
присваивается значению, переданному следующим вызовом it.next()
, что-то совершенно другое! Может быть немного полезно опустить круглые скобки и записать это как
var y = 2 * yield x + 1;
var z = yield y / 3;
имея в виду, что yield
— это оператор, а не вызов функции.
Что касается упомянутой вами ошибки, например, в traceur это «Отправлено значение в генератор новорожденных». Это имеет смысл, когда вы думаете об этом. Значение, отправляемое в качестве параметра it.next()
, становится значением последней доходности в генераторе. При первом вызове it.next()
в генераторе нет самого последнего результата yield, поэтому нечего принимать передаваемое значение, отсюда и ошибка.
Не путайте передачу параметров генератору (в вашем случае x
), который просто обеспечивает способ настройки или инициализации генератора, с передачей параметров it.next()
, которые служат значением самого последнего yield
в генераторе.
Может быть полезно подумать о том, как бы вы написали эквивалентный ручной генератор (упрощенный, чтобы просто возвращать следующее значение вместо {value, done}
и бросать, когда в генераторе нет газа):
function foo(x) {
var y, z, step = 0;
return function next(val) {
switch (step++) {
case 0: return x + 1; break;
case 1: y = 2 * val; return y / 3; break;
case 2: z = val; return x + y + z; break;
default: throw "generator finished";
}
};
}
Затем:
iterator = foo(5);
iterator(); // 6
iterator(12); // 8
iterator(13); // 42
person
Community
schedule
02.11.2014