2014-11-02 2 views
3

Для ES6 генераторов, почему автор this blog post сказать:ES6 Generators- Пример, где нет выражения выхода для первого следующий()

от: http://davidwalsh.name/es6-generators

«Первый в следующем (. .), мы ничего не отправляем. Почему? Потому что нет выражения доходности, чтобы получить то, что мы проходим ».

Не первый it.next() звонок (yield (x + 1))?

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 } 

Вы можете видеть, что мы все еще можем передать параметры (х в нашем примере) с начальным обув (5) Итератор-конкретизации вызова, так же как и с обычными функциями.

Первый следующий (..) звонок, мы ничего не отправляем. Зачем? Потому что нет никакого выражения выход получить то, что мы передаем.

ответ

6

Первый 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 это утверждение, а не вызов функции.

Что касается ошибки, которую вы упомянули, в трассировке, например, это «Отправлено значение новорожденному генератору». Это имеет смысл, когда вы об этом думаете. Значение, отправляемое как параметр в it.next(), становится значением последних выход в генераторе. При первом вызове it.next() там нет самого последнего выхода в генераторе, поэтому нет ничего, чтобы принять переданное значение, следовательно, ошибка.

Не следует путать передачи параметров генератора (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 

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

  • Нет связанных вопросов^_^