Javascript Generators вопрос - объясните этот код - PullRequest
5 голосов
/ 08 мая 2019

Я читаю "Справочник JavaScript" Флавио Скоупса.Он вводит понятие генераторов.

function* calculator(input) {
  var doubleThat = 2 * (yield(input / 2))
  var another = yield(doubleThat)
  return (input * doubleThat * another)
}

// He then runs the following code

const calc = calculator(10)
console.log(calc.next())

Выход

{value: 5, done: false}

calc.next(7);

Выход:

{value: 14, done: false}

Я понимаю первый вывод, но я не понимаю второй.Почему вывод 14?

Насколько я понимаю, в следующий раз, когда .next() вызывается на calc, он должен продолжаться в строке ПОСЛЕ той, на которой он последний раз останавливался.

Ну, вот эта строка: var another = yield(doubleThat) и значение переменной doubleThat в этой точке должно быть 10, поэтому я ожидаю, что второй yield вернет объект со значением 10.

Я не думаю, что пример в книге хороший, так как я понимаю концепцию Generators (Python) и Iterators (C ++ / Python), и я понимаю другие примеры Javascript Generators - ноЯ просто не понимаю, что здесь происходит.

Может кто-нибудь объяснить, почему значение, возвращаемое после calc.next(7), равно 14?

Ответы [ 2 ]

4 голосов
/ 08 мая 2019

Вызов .next(7) предоставляет значение для этого первого выражения yield, переопределяя значение 5, которое оно ранее вычисляло и возвращало. Это двусторонние отношения. Первая yield "пауза" в середине выражения, чтобы было ясно. Выполнение продолжается внутри этого выражения, а не следующего оператора.

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

3 голосов
/ 08 мая 2019
function* calculator(input) {
  var doubleThat = 2 * (yield(input / 2))
  var another = yield(doubleThat)
  return (input * doubleThat * another)
}

const calc = calculator(10)
console.log(calc.next()); 

В этот момент вы достигнете первой доходности, 10 / 2.

Тогда

calc.next(7);

код теперь такой

var doubleThat = 2 * (7) // yield expression transformed into 7

Для этого значение равно 14

Вы можете получить некоторое представление с помощью отладчика

function* calculator(input) {
  var doubleThat = 2 * (yield(input / 2))
  var another = yield(doubleThat)
  return (input * doubleThat * another)
}

const calc = calculator(10)
debugger;
console.log(calc.next()); 
debugger;
console.log(calc.next(7))

Единственное, что странно, это то, что когда вы вводите второе после следующего, отладчик выводит вас на вторую строку функции, по-видимому, не выполняя 2*7. Я думаю, это просто на первый взгляд, потому что это не останавливает середину выражения, но я могу ошибаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...