Почему Generator.prototype.return принимает значение? - PullRequest
2 голосов
/ 15 марта 2019

Я пытаюсь выяснить, почему Generator.prototype.return принимает значение.

Я получаю, что он останавливает обработку генератора и обрабатывает каждый next вызов с:

{
    done: true,
    value: undefined,
}

Но когда вы передаете ему значение, такое как generator.return(4), все, что он делает, это возвращает вам объект, как если бы вы назвали Generator.prototype.next, а ваша value опора равнялась 4.

Мое единственное предположение - этоможет быть полезно при составлении генераторов или при двусторонней связи;хотя, поскольку он убивает генератор, двусторонняя связь не имеет особого смысла.

1 Ответ

1 голос
/ 15 марта 2019

Метод .return() принимает значение, поскольку обеспечивает двустороннюю связь так же, как .next() и .throw().

A yield выражение может иметь 3 различных результата:

  • Он может вычисляться как простое выражение, в результате значение этого
  • Может оцениваться как оператор throw, вызывая исключение
  • Может оцениваться как оператор return, в результате чего перед завершением функции будут оцениваться только операторы finally.
  • (4-й возможный результат - генератор никогда не возобновит работу)

, которые достигаются путем вызова соответствующего метода на приостановленном генераторе с соответствующим значением. Это включает в себя значение исключения и возвращаемое значение.

Но когда вы передаете ему значение, такое как generator.return(4), все, что он делает, это возвращает вам объект, как если бы вы вызывали Generator.prototype.next, а значение вашего свойства было 4.

Не обязательно. Вы можете подумать, что когда вычисляется оператор return, он всегда возвращается с этим возвращаемым значением, и в отличие от исключения из оператора throw его невозможно перехватить. Это правда, что возвращаемое значение не может быть доступным в функции генератора, но оно может быть подавлено или изменено с помощью предложения finally.

[ function* exampleA() {
    try { yield; } finally {}
  },
  function* exampleB() {
    try { yield; } finally { yield 'Y'; }
  },
  function* exampleC() {
    try { yield; } finally { return 'Z'; }
  },
  function* exampleD() {
    try { yield; } finally { throw 'E' }
  }
].forEach(genFn => {
  try {
    const gen = genFn();
    gen.next();
    console.log(gen.return('X'));
  } catch(e) {
    console.log(e);
  }
});

(Конечно, делать такие вещи в предложении finally - это плохая практика, но это возможно)

...